c++ - 为什么在我没有传递类的实例时调用复制构造函数?

标签 c++ constructor initialization

我有一个类服务器,它有一个构造函数:

Server::Server(int port) {
    // initialize some class variables
    port_ = port;
    //...
}

我试着像这样创建一个类的实例:

int main(int argc, char** argv) {
    int port = 3000;
    Server server = Server(port);
}

我得到这个编译错误:

server_main.cpp:32:32: error: use of deleted function ‘Server::Server(const Server&)’
     Server server = Server(port);
                                ^

现在,我明白为什么复制构造函数被隐式删除了,但为什么要调用它呢?

如果我向类中添加一个复制构造函数,错误就会消失。有没有其他方法可以避免这种情况?

最佳答案

Server server = Server(port);copy initialization ;您正在从临时 Server 初始化 server

copy elision可能会发生,但在 C++17 之前不能保证。即使复制/移动构造函数可能不会被调用,但仍然必须存在且可访问(就像根本没有发生优化一样),否则程序格式错误。

您可以将其更改为 direct initialization ,它将直接调用 Server::Server(int):

Server server(port);

direct list initialization (自 C++11 起):

Server server{port};

编辑

自 C++17 起,copy elision在这种情况下是有保证的。

Under the following circumstances, the compilers are required to omit the copy- and move- constructors of class objects even if copy/move constructor and the destructor have observable side-effects:

  • In initialization, if the initializer expression is a prvalue and the cv-unqualified version of the source type is the same class as the class of the destination, the initializer expression is used to initialize the destination object:

    T x = T(T(T())); // only one call to default constructor of T, to initialize x

因此您的代码将适用于 C++17;为了保证复制省略,不需要访问复制/移动构造函数。

LIVE DEMO from GCC

关于c++ - 为什么在我没有传递类的实例时调用复制构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39971659/

相关文章:

c# - 未初始化的串行端口属性是否像使用默认构造函数时一样被赋予默认值?

c++ - 如何从 C++ 中的未命名派生类调用非默认父构造函数?

perl - 给定/当值未定义时

c++ - 如何在 Eclipse 中使用 MinGW 编译 boost 线程?

c++ - Eclipse CDT : Symbol 'cout' could not be resolved

c++ - 如何将 10 位值分配给字节数组?

c - 尝试.c :8: error: incompatible types in initialization - c

c++ - 如何更有效地使用模板在 C++ 中实现带有绑定(bind)检查的二维数组?

c++ - 将指向数据成员的指针传递给基类构造函数是否安全?

unit-testing - 测试期间的 Scalatra Servlet init() (Jetty ServletTester)