Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 8 of 8

Thread: still struggling with c++ syntax :)

  1. #1

    still struggling with c++ syntax :)

    Hi everybody!

    I'm trying to create a no-arguments-provided-version of a class constructor, this is my code:

    Code:
    //empty Constructor
    SkyFlash::SkyFlash(): poti(SkyPoti()), bounce(0, 0) {
    }
    
    //Constructor
    SkyFlash::SkyFlash(SkyPoti& Poti, int pin) : poti(Poti), bounce(pin, 10) {
    	pinMode(pin, INPUT_PULLUP);
    	
    }
    and this is the error message:

    Arduino: 1.8.8 (Windows 10), TD: 1.45, Board: "Teensy 3.5, MIDI, 120 MHz, Faster, US English"

    ...\libraries\SkyController\SkyFlash.cpp: In constructor 'SkyFlash::SkyFlash()':

    ...\libraries\SkyController\SkyFlash.cpp:7:51: error: invalid initialization of non-const reference of type 'SkyPoti&' from an rvalue of type 'SkyPoti'

    SkyFlash::SkyFlash(): poti(SkyPoti()), bounce(0, 0) {

    ^
    Your help will be highly appreciated!
    Robert

    P.S.: You can find the whole project in the .zip file
    Attached Files Attached Files

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    8,058
    Can you post a simple example to cut/paste into the IDE without needing zip download/extract …

    Does this cover the intent? correct-way-of-initializing-a-struct-in-a-class-constructor

  3. #3
    Quote Originally Posted by defragster View Post
    Can you post a simple example to cut/paste into the IDE without needing zip download/extract

    Ok. This compiles:

    Code:
    class testclass1 {
      public:
        testclass1 ();
      private:
    };
    
    testclass1::testclass1 () {
    }
    
    
    class testclass2 {
      public: 
        testclass2(testclass1& test);
        
      private:
        testclass1& _test;
    };
    
    testclass2::testclass2(testclass1& test): _test(test) {
      
    }
    
    
    void setup() {
      // put your setup code here, to run once:
    
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    
    }
    while this unfortunately doesn't compile:

    Code:
    class testclass1 {
      public:
        testclass1 ();
      private:
    };
    
    testclass1::testclass1 () {
    }
    
    
    class testclass2 {
      public: 
        testclass2();
        testclass2(testclass1& test);
        
      private:
        testclass1& _test;
    };
    
    testclass2::testclass2() {
      
    }
    
    testclass2::testclass2(testclass1& test): _test(test) {
      
    }
    
    
    void setup() {
      // put your setup code here, to run once:
    
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    
    }
    I have to somehow initialize _test without giving the constructor an argument. I tried:

    Code:
    class testclass1 {
      public:
        testclass1 ();
      private:
    };
    
    testclass1::testclass1 () {
    }
    
    
    class testclass2 {
      public: 
        testclass2();
        testclass2(testclass1& test);
        
      private:
        testclass1& _test;
    };
    
    testclass2::testclass2() : _test(testclass1()) {
      
    }
    
    testclass2::testclass2(testclass1& test): _test(test) {
      
    }
    
    
    void setup() {
      // put your setup code here, to run once:
    
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    
    }
    But that doesn't work either.

  4. #4
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    8,058
    Was the link ... added after initial posting … on point? The second example seemed relevant.

    IIRC - in this environment it was found that doing things [calling code outside your code?] in the constructor is problematic and IIRC was best done in a .begin() in setup() after the machine was ready to run.

  5. #5
    To be honest, I don't fully understand the content of your link and I don't exactly get how it relates to my problem.

    First I had the equivalent to this code:

    Code:
    class testclass1 {
      public:
        testclass1 ();
      private:
    };
    
    testclass1::testclass1 () {
    }
    
    
    class testclass2 {
      public: 
        testclass2(testclass1& test);
        
      private:
        testclass1& _test;
    };
    
    testclass2::testclass2(testclass1& test): _test(test) {
      
    }
    
    
    void setup() {
      // put your setup code here, to run once:
    
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    
    }
    and it nicely worked. But now I need a default constructor. It doesn't need to create a working object, I just need it as a dummy to initialize an array of objects. But I don't know how to write this default constructor without changing the rest of the code.

  6. #6
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,734
    Maybe like this? (does compile)

    Code:
    class testclass1 {
      public:
        testclass1 ();
      private:
    };
    
    testclass1::testclass1 () {
    }
    
    
    testclass1 default_instance_of_testclass1;
    
    
    class testclass2 {
      public: 
        testclass2();
        testclass2(testclass1& test);
        
      private:
        testclass1& _test;
    };
    
    testclass2::testclass2() : _test(default_instance_of_testclass1) {
      
    }
    
    testclass2::testclass2(testclass1& test): _test(test) {
      
    }
    
    
    void setup() {
      // put your setup code here, to run once:
    
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    
    }

  7. #7
    Quote Originally Posted by PaulStoffregen View Post
    Maybe like this? (does compile)
    Simple but effective. Thank you! Again.

  8. #8
    Senior Member
    Join Date
    Feb 2017
    Posts
    272
    The whole mess can be avoided by not trying to have a member variable that's a reference to a 'testclass1' object. Use a pointer instead. Then you can have a separate member function to set the pointer as desired - regardless of which construct was used to originally create the object:
    Code:
    class testclass1 {
      public:
        testclass1 ();
      private:
    };
    
    testclass1::testclass1 () {
    }
    
    class testclass2 {
      public:
        testclass2();
        testclass2(testclass1& test);
        void setPointer(testclass1& test);
    
      private:
        testclass1 *_test = nullptr;
    };
    
    testclass2::testclass2() {
    }
    
    testclass2::testclass2(testclass1 &test): _test(&test) {
    }
    
    void testclass2::setPointer(testclass1 &test) {
      _test = &test;
    }
    
    void setup() {
    }
    
    void loop() {
    }
    BTW, next time you post example code, PLEASE try to use identifiers that don't all look so similar: testclass1, testclass2, test, _test, etc. Use a little imagination!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •