使用 class 构造函数初始化指向 class 对象的指针?
pointer to class objects initialization with 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's area: " << obj.area() << '\n';
cout << "*foo's area: " << foo->area() << '\n';
cout << "*bar's area: " << bar->area() << '\n';
cout << "baz[0]'s area:" << baz[0].area() << '\n';
cout << "baz[1]'s area:" << baz[1].area() << '\n';
delete bar;
delete[] baz;
return 0;
}
我对这里的这行代码有点(没有双关语意)困惑:
baz = new Rectangle[2] {{2,5}, {3,6}};
我见过这样的代码:
int *foo = new int[3] {1,2,3};
我完全理解。但是这里 {{2,5}, {3,6}}
的语法是什么? class 对象数组如何像这样初始化?我搜索了很多在线 c++ 参考资料,但没有任何线索。
只需使用初始化列表来填充数组中的两个矩形。
想到:
{2,5}, {3,6}
就像调用 Rectangle{2,5}、Rectangle{3,6} 一样。
Rectangle
构造函数需要两个 int
。
如果你看行 Rectangle obj (3, 4);
这也可以是 Rectangle obj {3, 4};
baz = 新矩形[2] { {2,5}, {3,6} };
不可编译。
甚至,
int * abc = new int[3] {1,2,3} ;
不可编译。
如果您想使用非默认构造函数创建一个矩形 class 数组,请执行以下操作:
Rectangle baz[] = { Rectangle(2,5) , Rectangle(3,6) };
如有不明之处请告知
(注意这只适用于C++11及以后的版本)
baz = new Rectangle[2] { {2,5}, {3,6} };
此语法称为 list-initialization。
列表初始化一个集合,例如数组结果(不出所料)在每个元素上 aggregate initialization, which will perform copy-initialization;由于此处的初始化程序本身是列表,因此导致 copy-list-initialization.
当您列表初始化一个(非聚合)class 时,编译器会查找构造函数并选择最佳匹配。如果所选构造函数需要对任何参数进行缩小转换(例如 double
-> int
),或者如果它是 explicit
构造函数,此时您将收到错误消息因为 copy-list-initialization 是 copy-initialization 的一种形式;只有 direct-initialization 例如 Rectangle r{2, 5};
可以使用 explicit
构造函数(尽管缩小转换仍然是一个错误)。
使用 C++11 可以使用 {x, y, z}
初始化对象实例。例如:
struct P2d {
double x, y;
};
void foo(P2d p);
void bar() {
foo({10, 20}); // Compiles fine
}
用在数组上可以,简单的情况下也可以。在更复杂的情况下,它只会增加混乱,因为您只能看到这些值,但您不知道这些值的用途。
这就像 API 像
一样使用
createWindow(0, 0, true, NULL, NULL, 1, NULL, false);
这些值有什么用?
只是不要过度使用新的大括号初始化...有些情况下它很棒:
// 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};
}
但有些情况只会让事情变得更糟:
{Rect(2, 3), Rect(4, 5)}
实际上比
更具可读性
{{2, 3}, {4, 5}}
(请记住,阅读代码时的易用性比编写代码时的易用性重要得多...大多数代码行都已编写一次阅读多次)
// 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's area: " << obj.area() << '\n';
cout << "*foo's area: " << foo->area() << '\n';
cout << "*bar's area: " << bar->area() << '\n';
cout << "baz[0]'s area:" << baz[0].area() << '\n';
cout << "baz[1]'s area:" << baz[1].area() << '\n';
delete bar;
delete[] baz;
return 0;
}
我对这里的这行代码有点(没有双关语意)困惑:
baz = new Rectangle[2] {{2,5}, {3,6}};
我见过这样的代码:
int *foo = new int[3] {1,2,3};
我完全理解。但是这里 {{2,5}, {3,6}}
的语法是什么? class 对象数组如何像这样初始化?我搜索了很多在线 c++ 参考资料,但没有任何线索。
只需使用初始化列表来填充数组中的两个矩形。
想到:
{2,5}, {3,6}
就像调用 Rectangle{2,5}、Rectangle{3,6} 一样。
Rectangle
构造函数需要两个 int
。
如果你看行 Rectangle obj (3, 4);
这也可以是 Rectangle obj {3, 4};
baz = 新矩形[2] { {2,5}, {3,6} };
不可编译。
甚至,
int * abc = new int[3] {1,2,3} ;
不可编译。
如果您想使用非默认构造函数创建一个矩形 class 数组,请执行以下操作:
Rectangle baz[] = { Rectangle(2,5) , Rectangle(3,6) };
如有不明之处请告知
(注意这只适用于C++11及以后的版本)
baz = new Rectangle[2] { {2,5}, {3,6} };
此语法称为 list-initialization。
列表初始化一个集合,例如数组结果(不出所料)在每个元素上 aggregate initialization, which will perform copy-initialization;由于此处的初始化程序本身是列表,因此导致 copy-list-initialization.
当您列表初始化一个(非聚合)class 时,编译器会查找构造函数并选择最佳匹配。如果所选构造函数需要对任何参数进行缩小转换(例如 double
-> int
),或者如果它是 explicit
构造函数,此时您将收到错误消息因为 copy-list-initialization 是 copy-initialization 的一种形式;只有 direct-initialization 例如 Rectangle r{2, 5};
可以使用 explicit
构造函数(尽管缩小转换仍然是一个错误)。
使用 C++11 可以使用 {x, y, z}
初始化对象实例。例如:
struct P2d {
double x, y;
};
void foo(P2d p);
void bar() {
foo({10, 20}); // Compiles fine
}
用在数组上可以,简单的情况下也可以。在更复杂的情况下,它只会增加混乱,因为您只能看到这些值,但您不知道这些值的用途。
这就像 API 像
一样使用 createWindow(0, 0, true, NULL, NULL, 1, NULL, false);
这些值有什么用?
只是不要过度使用新的大括号初始化...有些情况下它很棒:
// 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};
}
但有些情况只会让事情变得更糟:
{Rect(2, 3), Rect(4, 5)}
实际上比
更具可读性{{2, 3}, {4, 5}}
(请记住,阅读代码时的易用性比编写代码时的易用性重要得多...大多数代码行都已编写一次阅读多次)