How to create class member objects initialized during constructor

I am primarily a C # programmer, but the project I'm working on uses me using C ++. In C #, I have the ability to define a member of a class where the member is null before it is initialized. For instance:

Class Foo{ private Bar _bar; public Foo(int valueBarNeeds){ _bar = new Bar(valueBarNeeds); } } 

The value of _bar is null, and access is denied until it is initialized. The rationale for this use case is that the constructor for the private object relies on some value that is unknown before the parent class is created.

Now, in C ++, I'm trying to do the same:

 class Foo{ public: Foo(int valueBarNeeds){ _bar = new Bar(valueBarNeeds); } private; Bar _bar; }; 

The compiler throws an error saying that there is no constructor for the bar that accepts null arguments. I understand that in C ++, the new keyword means something completely different. Within the framework of this difference, you can determine the objects that are located at the end of the method, without manual deletion, declaring without the keyword new .

 SomeFunc(){ int valueBarNeeds = 100; Bar _bar(valueBarNeeds); _bar.SomeFunc(); } 

_bar is removed when the method stack goes out of scope.

Then that asks my question. If the syntax that I use in C # to create unified objects actually tries to initialize objects in C ++ ... How do I create a unified type available for the rest of the class methods that is created by the constructor of the parent objects?

+6
source share
2 answers

The problem is that what you call “initialization” does not actually exist. Any members that are initialized, implicitly or explicitly, are initialized before the program enters your constructor.

In your code snippets, only the destination is displayed; it doesn't matter that you do this in the constructor body for the encapsulating object. This is still just an appointment.

Bar is a class, so your _bar member will be implicitly initialized, but in fact it cannot be, because the class does not have a constructor without arguments. To provide arguments, you must explicitly initialize this element yourself.

In C ++, we initialize the following elements:

 class Foo { public: Foo(int valueBarNeeds) : _bar(valueBarNeeds) {} private: Bar _bar; }; 

You are also right to misunderstand new ; unlike Java, it should be used sparingly, since objects are fundamentally created by a simple declaration (and, if necessary, their definition). The use of new reserved for dynamic allocation in free storage and returns a pointer to use; this use should be rare. You have successfully fixed this in your final code snippet.

How to create a unified type available for other methods of the class, which is created by the constructor of parent objects?

If a member has a class type, it will always be initialized. You cannot have an object that does not exist. The closest you can get is encapsulating a pointer, not an object:

 class Foo { public: Foo(int valueBarNeeds) : _bar(nullptr) { // some time later... _bar = new Bar(valueBarNeeds); } private: Bar* _bar; }; 

But this opens up a can of worms with regard to memory management and much more, and as explained above, you should avoid this if you really don't need it. Alternatives include smart pointers, but if possible, you should still adhere to the standard encapsulation of swamp objects. It should be rare that you need to consciously leave the object in an invalid state for a while.

+3
source

You give your class a data member of this type and initialize it in the constructor initialization list:

 class Foo { public: Foo(int valueBarNeeds) :_bar(valueBarNeeds) {} private: Bar _bar; }; 

Once you are in the constructor body, all data members have been initialized. If you do not explicitly initialize them in the constructor initialization list, they are initialized by default, which means that the default constructor is called for custom types, and for built-in types, initialization is not performed.

+2
source

Source: https://habr.com/ru/post/957793/


All Articles