Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid calling constructor of member variable

I have the following C++-class:

// Header-File
class A
{
    public:
    A();

    private:
    B m_B;
    C m_C;
};

// cpp-File
A::A()
: m_B(1)
{
    m_B.doSomething();
    m_B.doMore();
    m_C = C(m_B.getSomeValue());
}

I now would like to avoid the class A to call any constructor of C m_C. Because on the last line in A::A(), I'm anyways going to initialize m_C myself because I need to prepare m_B first. I could provide an empty default constructor for class B. But that's not the idea.

I have already tried to add m_C(NULL) to the init-list of A::A(). Sometimes it worked, sometimes it said there was no constructor taking NULL as an argument.

So how can I have m_C left uninitialized? I know that with pointers, the m_C(NULL)-way works. And I don't want to allocate it dynamically using new.

Any idea is appreciated.

like image 712
Atmocreations Avatar asked Oct 20 '11 09:10

Atmocreations


People also ask

Can I call constructor in member function?

Constructor and destructor can also be called from the member function of the class. Example: CPP.

Does C++ automatically call constructor?

A constructor in C++ is a special method that is automatically called when an object of a class is created.

Why constructor is called special member function?

Answer: A constructor can be defined as a special member function which is used to initialize the objects of the class with initial values. It is special member function as its name is the same as the class name. It enables an object to initialize itself during its creation.

Can you declare a variable in a constructor?

Constructors act like any other block of code (e.g., a method or an anonymous block). You can declare any variable you want there, but it's scope will be limited to the constructor itself.


2 Answers

What you ask is forbidden - and correctly so. This ensures that every member is correctly initialized. Do not try to work around it - try to structure your classes that they work with it.

Idea:

  • C has a constructor that does nothing
  • C has an initialization method that makes the class usable
  • C tracks whether it has been initialized correctly or not and returns appropriate errors if used without initialization.
like image 160
Tobias Langner Avatar answered Oct 31 '22 02:10

Tobias Langner


How about using technique described in this QA?

Prevent calls to default constructor for an array inside class

std::aligned_storage<sizeof(T[n]), alignof(T)>::type

Or, you also can consider using of union. AFAIK, unions will be initialized only with first named member's constructor.

For example,

union
{
   uint8_t _nothing = 0; 
   C c;
};

According to the standard mentioned in the QA, c will be zero-initialized, and its constructor will not be called.

like image 31
eonil Avatar answered Oct 31 '22 02:10

eonil