实例化类的正确方法
The correct ways about Instantiating class
这两种实例化类的方式都是可以接受的吗?我的意图是在堆栈上而不是堆上创建CBox
CBox a=CBox(1);
CBox b(2);
CBox的定义如下:
class CBox
{
public:
int abc;
CBox(int var){
abc=var;
}
};
实际上,由于在第一个定义中省略了复制/移动构造函数,这两个定义是等效的。
CBox a=CBox(1);
CBox b(2);
唯一的区别是,如果复制/移动构造函数不可访问或可能不会被隐式调用(例如,它是私有的或定义为已删除的或具有显式的函数说明符),那么第一条语句将不会被编译,除非MS vc++有自己的语言扩展,通常只是编译器错误。
如果你有一个这样的类定义:
class A
{
public:
int q;
A() {
std::cout << "Constructor without argument" << std::endl;
}
A(int x) : q(x) {
std::cout << "Constructor" << std::endl;
}
A(const A& a) {
std::cout << "Copy Constructor" << std::endl;
this->q = a.q;
}
A& operator=(const A& a) {
std::cout << "Assignment operator" << std::endl;
if(&a != this) this->q = a.q;
return *this;
}
};
则得到以下结果:
int main(int argc, char** argv)
{
A a(2); // uses constructor
A b = A(3); // uses constructor (exact same as A b(3);)
A c = b; // uses copy constructor
A d; // uses constructor without parameter
c = d; // uses assignment operator
}
作为注释:在c++ 11中,您还可以编写A a{2};
,以避免与函数调用混淆。
所以总结一下:只要写A a(2);
-或者如果你使用c++ 11 A a{2};
。
标准的相关部分为(n3797)8.5/17。
否则(即,对于剩余的复制初始化情况),可以从源转换的用户定义转换序列类型为目标类型或(当使用转换函数时)的派生类,如13.3.1.4所述,并通过过载解析(13.3)选择最佳的一个。如果转换不能完成或有歧义,初始化是不规范的。选定的函数用初始化器调用表达作为它的论据;如果函数是构造函数,则调用类的非限定版本的临时对象初始化目的地类型。临时值是一个右值。调用的结果(这是构造函数情况下的临时)然后用于根据上面的规则,直接初始化对象拷贝初始化的目标。在某些情况下,一个允许实现消除其中固有的复制通过直接构造中间结果进行直接初始化被初始化的对象;参见12.2、12.8。
意思是,给定代码:
CBox a=CBox(1);
CBox b(2);
如果满足某些(合理的)条件,这两段代码将在符合标准的编译器中执行完全相同的操作。没有临时生成,没有赋值操作,也没有复制。在这两种情况下,调用构造函数直接初始化对象本身。
我发现标准不清楚这是否是copy elision
,因为这里没有使用该术语。在12.8/31中有涉及。
在回答这个问题时,使用哪个取决于可读性和其他因素。
相关文章:
- 使用动态实例化的对象填充矢量的快速方法
- 检查类是否在方法中实例化
- 从 c++ 中的实例化进程获取输出的可靠方法是什么?
- 使用包含互斥锁的类的方法实例化 cpp11 线程
- 实例化对象并调用方法,使用单行语法在 C# 或 C++ 中返回值?
- 当c++实例化方法?
- 我们可以在没有新实例化的情况下声明一个抽象方法来返回抽象超类中的子类对象吗
- C++ 实例化新对象时不接受继承方法默认参数值
- 实例化新类时未调用的方法
- 找不到使用 bitset 实例化模板函数的有效方法
- 无法实例化抽象类,但类不是抽象/派生方法的参数
- 有没有一种优雅的方法可以从 std::vector 实例化 boost::array
- 使用类方法而不实例化
- 一种安全、符合标准的方法,使类模板专用化仅在实例化时才无法使用"static_assert"进行编译
- C++17 单独的显式方法模板实例化声明和定义
- 如何实例化多个 set 对象来测试 Set 类的各种构造函数和方法
- 模板类方法的部分专用化或实例化
- 使用自动>decltype方法显式实例化函数
- 隐式模板方法实例化
- 用虚方法实例化类,但不进行堆分配