A pointer to initializing class objects using the class constructor?

// pointer to classes example // runs with no problem #include <iostream> using namespace std; class Rectangle { int width, height; public: Rectangle(int x, int y) : width(x), height(y) {} int area(void) { return width * height; } }; int main() { Rectangle obj (3, 4); Rectangle * foo, * bar, * baz; foo = &obj; bar = new Rectangle (5, 6); baz = new Rectangle[2] { {2,5}, {3,6} }; cout << "obj area: " << obj.area() << '\n'; cout << "*foo area: " << foo->area() << '\n'; cout << "*bar area: " << bar->area() << '\n'; cout << "baz[0] area:" << baz[0].area() << '\n'; cout << "baz[1] area:" << baz[1].area() << '\n'; delete bar; delete[] baz; return 0; } 

I am a bit (no pun intended) to confuse this line of code here:

 baz = new Rectangle[2] {{2,5}, {3,6}}; 

I saw code like:

 int *foo = new int[3] {1,2,3}; 

and I fully understand that. But what is the syntax {{2,5}, {3,6}} here? How can I initialize an array of class objects as follows? I was looking for a lot of C ++ references, but I have no idea.

+4
source share
4 answers

(Note that this only applies to C ++ 11 and later)

 baz = new Rectangle[2] { {2,5}, {3,6} }; 

This syntax is called list-initialization .

A collection initialization list, such as an array, is (not surprisingly) in aggregate initialization , which will perform copy-initialization for each element; since the initializers here are the lists themselves, this leads to the initialization of the copy list.

When you list-initialize a (non-aggregate) class, the compiler looks at the constructors and selects the best match. You will get an error at this point if the selected constructor requires a narrowing conversion of any of the arguments (for example, doubleint ), or if it is an explicit constructor, because copy list initialization is a form of copy-initialization; direct-initialization only , for example Rectangle r{2, 5}; , may use explicit constructors (although narrowing conversions is still a mistake).

0
source

Just use initialization lists to fill both rectangles in the array.

Think:

 {2,5}, {3,6} 

Like just calling Rectangle {2,5}, Rectangle {3,6}.

The Rectangle constructor takes two int . If you look at the line Rectangle obj (3, 4); It can also be a Rectangle obj {3, 4};

0
source

With C ++ 11, you can initialize an instance of an object using {x, y, z} . For instance:

 struct P2d { double x, y; }; void foo(P2d p); void bar() { foo({10, 20}); // Compiles fine } 

Using it for arrays is fine, and this is also normal for simple cases. In more complex cases, this simply increases confusion, because you only see the values, but you don’t know why these values ​​are used.

This is similar to using an API like

  createWindow(0, 0, true, NULL, NULL, 1, NULL, false); 

What are these values ​​for?

Just don't overdo the new braces initialization ... there are times when it's fantastic:

 // C++03 std::vector<int> list_of_values() { std::vector<int> result; result.push_back(1); result.push_back(2); result.push_back(3); return result; } // C++11 std::vector<int> list_of_values() { return {1, 2, 3}; } 

but there are cases in which it is just getting worse:

 {Rect(2, 3), Rect(4, 5)} 

actually more readable than

 {{2, 3}, {4, 5}} 

(remember that ease when reading code is much more important than simplicity when writing code ... most lines of code are written once and read many times)

0
source

baz = new rectangle [2] {{2,5}, {3,6}};

not compiled.

Even,

 int * abc = new int[3] {1,2,3} ; 

not compiled.

If you want to create an array of the Rectangle class with a non-default constructor, do the following:

  Rectangle baz[] = { Rectangle(2,5) , Rectangle(3,6) }; 

Please let me know if this is not clear.

-one
source

All Articles