C++ Super-FAQ 『Constructor』
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ Super-FAQ 『Constructor』相关的知识,希望对你有一定的参考价值。
- 什么是构造函数
- List x, List x()与List x(Bar())
- 在构造函数中能否调用本类型的其他构造函数
1 vector<Fred> a(10, Fred(5,7)); 2 Fred b[10];
Fred a[10] = { Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7), // The 10 Fred objects are Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7) // initialized using Fred(5,7) };
- 构造函数initialization list的调用顺序
Immediate base classes (left to right), then member objects (top to bottom).
注意:
若member objects包含嵌套,则必须将被嵌套的对象声明在前。
initialize list按照member objects声明的顺序初始化。
若一个成员变量的初始化使用另一成员变量的值时,必须明确表明他们的声明顺序。
- 在构造函数中访问this指针
在构造函数体({})内,可以访问this指针,因为此时所有的数据成员已经准备完毕。
但在构造函数中无法访问派生类override的虚函数,因为此时this还不知道它是一个派生类对象。
- Named Constructor Idiom
这是一种能够提供更直观、更安全地构造类的技术。
若一种类型含有许多构造函数,仅仅通过参数类型不易区分他们,这时就可采用『Named Constructor Idiom』。
比如,点坐标既能使用笛卡尔坐标系也能使用极坐标系,而他们的构造参数一致。这时可将他们的普通构造函数声明为私有,然后通过Named Constructor供用户构造访问。
Point p1 = Point::rectangular(5.7, 1.2); // Obviously rectangular Point p2 = Point::polar(5.7, 1.2); // Obviously polar
若使用者需确保对象必须通过new创建,也可使用该技术。
- return-by-value是否意味着额外开销
不一定。
因为在某些用法下,(商业级)编译器会自动优化,将局部对象的指针而不是副本返回。
class Foo; Foo Method(){ return Foo(...); } void Func() { Foo x = Method(); //会优化 Foo y; y = Method(); //不一定优化 }
- 类的static成员声明
除声明static成员外,代码中还必须包含该对象的定义,否则会导致链接错误『undefined external』。
若声明static const成员,则定义时不能通过=对其初始化。
static
initialization order fiasco
这是一种极难被发现的细微错误,该错误一般发生在main()被调用之前。
eg: 在A.cpp中定义static X x,在B.cpp中定义static Y y,且y的初始化需要用到x,若在y初始化前x未初始化,则会出现该错误。
// File x.cpp #include "Fred.h" //方式一 Fred x; //方式二 Fred& x() { static Fred* ans = new Fred(); return *ans; } // File y.cpp #include "Barney.h" Barney y; // File Barney.cpp #include "Barney.h" //方式一 Barney::Barney() { // ... x.goBowling(); // ... } //方式二 Barney::Barney() { // ... x().goBowling(); // ... }
eg: 一种通过前置声明在对象初始化前访问该对象的例子。
int f(); // forward declaration int g(); // forward declaration int x = f(); int y = g(); int f() { std::cout << "using ‘y‘ (which is " << y << ")\n"; return 3*y + 7; } int g() { std::cout << "initializing ‘y‘\n"; return 5; }
- Named Parameter Idiom
File f = OpenFile("foo.txt") .readonly() .createIfNotExist() .appendWhenWriting() .blockSize(1024) .unbuffered() .exclusiveAccess(); class File { public: File(const OpenFile& params); // ... };
此处的OpenFile就是新创建的类,通过他的成员函数可以对File的属性参数进行设置。
- 关键字explicit
该关键字可用于构造函数和转换操作符的修饰。目的是用户使用这些函数时必须显示调用,避免隐式类型转换的问题。
参考资料:https://isocpp.org/wiki/faq/ctors
以上是关于C++ Super-FAQ 『Constructor』的主要内容,如果未能解决你的问题,请参考以下文章
C++ Super-FAQ 『Operator Overloading』
C++ Super-FAQ 『Classes and Objects』
Uncaught TypeError: Cannot read properties of undefined (reading ‘Constructo