Thread: New to C++, confused about creating instance of class

  1. #1
    Registered User
    Join Date
    Jul 2002
    Posts
    35

    New to C++, confused about creating instance of class

    Kind of not understanding how classes work. Particularly when an instance of the class is created.

    I am new to C++ but I have programming in C for a few years.

    Based on the book that I am learning c++ from in a constructor anything past the : is a parameter list.

    I2SMEMSSampler is a derived class of I2SSampler. I pass 3 params to I2SMEMSSampler but the parameter list only accepts two parameters (in cpp file)

    Can someone tell me what is going on when an object of class I2SMEMSSampler is created from main.cpp ?

    Here is the code in question.

    In main.cpp I have this line:
    Code:
      I2SSampler *input = new I2SMEMSSampler(I2S_NUM_0, i2s_mic_pins, i2s_mic_Config);
    which is declared in an h file like this:
    Code:
    class I2SMEMSSampler : public I2SSampler
    {
    private:
        i2s_pin_config_t m_i2sPins;
        bool m_fixSPH0645;
    
    protected:
        void configureI2S();
    
    public:
        I2SMEMSSampler(
            i2s_port_t i2s_port,
            i2s_pin_config_t &i2s_pins,
            i2s_config_t i2s_config,
            bool fixSPH0645 = false);
        virtual int read(int16_t *samples, int count);
    };
    in the cpp file it is defined like this, I don't understand the significance of what comes after the colon because when i create an object of the class I am giving the constructor 3 parameters as shown above in main.cpp;
    Code:
    I2SMEMSSampler::I2SMEMSSampler(
        i2s_port_t i2s_port,
        i2s_pin_config_t &i2s_pins,
        i2s_config_t i2s_config,
        bool fixSPH0645) : I2SSampler(i2s_port, i2s_config) 
    {
        m_i2sPins = i2s_pins;
        m_fixSPH0645 = fixSPH0645;
    }

  2. #2
    Registered User
    Join Date
    Dec 2017
    Posts
    1,664
    I don't understand the significance of what comes after the colon
    It's passing two of the parameters to the base class in order to initialize it.
    The remaining two parameters are set in the derived class (the last of which has a default value given in the header).
    Do you understand this simplified (and complete) example? It has basically the same structure.
    Code:
    #include <iostream>
    
    class Base {
    protected:
        int a_, b_;
    public:
        Base(int a, int b) : a_(a), b_(b) {
            std::cout << "Base ctor\n";
        }
        virtual void print() const = 0;
        virtual ~Base() {
            std::cout << "Base dtor\n";
        }
    };
    
    class Derived : public Base {
        int c_, d_;
    public:
        Derived(int a, int b, int c, int d = 0) : Base(a, b), c_(c), d_(d) {
            std::cout << "Derived ctor\n";
        }
        void print() const override {
            std::cout << a_ << ' ' << b_ << ' ' << c_ << ' ' << d_ << '\n';
        }
        ~Derived() {
            std::cout << "Derived dtor\n";
        }
    };
    
    int main() {
        Base *b = new Derived(1, 2, 3);
        b->print();
        delete b;
    }
    Last edited by john.c; 07-09-2024 at 12:54 PM.
    All truths are half-truths. - A.N. Whitehead

  3. #3
    Registered User
    Join Date
    Jul 2002
    Posts
    35
    I had to dig around my book which ended up having the info that explained the order of constructors and destructors.
    Now I understand your example and also the one I posted.
    The book had a very basic example that showed how a base class can be initialized by passing parameters to it from a derived class.
    So good on the book and bad on me.
    Also found, "base class objects are instantiated before a derived class" and "the sequence of destructors is opposite to that of constructors"
    So now I understand the order of constructors and destructors are standardized.


    Thank you john c.

  4. #4
    Registered User
    Join Date
    Jan 2010
    Posts
    233

    Question Query

    Hi there,

    Whilst I have complete faith in the code posted, I was just curious if this part here:

    Code:
    class Derived : public Base 
    {
        int c_, d_;
    public:
        Derived(int a, int b, int c, int d = 0) : Base(a, b), c_(c), d_(d)
        {
            std::cout << "Derived ctor\n";
        }
    
    ....
    would perhaps give a compile warning as there's a pure virtual function in the base class definition? I'm aware that when you create an instance of a child class the base class's constructor is also called (usually first if I remember correctly?). I'm just curious as how the compiler would handle this given that the base is an abstract class with a pure virtual?

    Thanks

  5. #5
    Registered User
    Join Date
    Dec 2017
    Posts
    1,664
    I'm not exactly sure what your concern is. You seem to be thinking that we can't call Base's ctor since the Base class is abstract in that it has no definition for print() and therefore could not be instantiated on its own. But it is not being instantiated on its own. It's being instantiated as the base of the Derived class, and Derived provides the definition for print(). Obviously we couldn't call Base::print() since it has no definition. But we are only calling Base's ctor and dtor, both of which exist.

    Note that we are saving the address of the newly constructed Derived class in a Base class pointer. The virtual Base::print (pure or not) allows access to Derived::print through the Base pointer through the vtable mechanism.

    An interesting detail is that the Base dtor needs to be virtual or it won't call the Derived dtor when the derived object is deleted. (Try removing virtual and you will see that Derived's dtor isn't called.)
    All truths are half-truths. - A.N. Whitehead

  6. #6
    Registered User
    Join Date
    Jan 2010
    Posts
    233
    You're as brilliant as ever John. That's a great and detailed reply. Thank you so much

  7. #7
    Registered User
    Join Date
    Aug 2024
    Posts
    1
    Hey! I understand that classes in C++ can be a bit confusing, especially when creating an instance of a class. Since you have experience in C, you'll probably pick it up quickly. In a class constructor, everything after the colon is a parameter list. The I2SMEMSSampler class inherits from I2SSampler. You pass 3 parameters to I2SMEMSSampler, but the parameter list only accepts two (in the cpp file). When you create an object of the I2SMEMSSampler class from main.cpp, the I2SSampler constructor is called with the first two parameters. The I2SMEMSSampler constructor is called with the third parameter. Hope this helps! Let me know if you have any other questions.

    Elliot :-)
    Last edited by Salem; 08-21-2024 at 10:54 AM. Reason: snipped spammy url

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Creating instance of a structure
    By Jimmy589 in forum C Programming
    Replies: 3
    Last Post: 04-05-2017, 06:14 AM
  2. Creating a class instance (am i going insane?!)
    By JonathanS in forum C++ Programming
    Replies: 3
    Last Post: 12-04-2012, 04:45 AM
  3. Declaring an instance of a class inside a class
    By nickodonnell in forum C++ Programming
    Replies: 4
    Last Post: 10-01-2005, 11:46 PM
  4. creating class instance from a file
    By Callith in forum C++ Programming
    Replies: 1
    Last Post: 11-25-2004, 09:03 PM
  5. creating a new instance of a function?
    By Geolingo in forum C++ Programming
    Replies: 17
    Last Post: 07-18-2003, 09:39 AM

Tags for this Thread