【问题标题】:Why I am getting the Constructor and the copy constructor called here? [duplicate]为什么我在这里调用构造函数和复制构造函数? [复制]
【发布时间】:2013-11-22 12:27:15
【问题描述】:

我有很多必须用 C++ 编写的 C# 代码。我在 C++ 方面没有太多经验。

我正在使用 Visual Studio 2012 进行构建。该项目是C++ 中的静态库(不是 C++/CLI)。

我有一个带有静态私有成员的静态方法的类。 当我调试时,我可以看到构造函数和复制构造函数都被调用。 我不明白为什么两者都被调用,我以为只有一个会。 有没有一种方法可以让我只调用一个构造函数?

这是我的代码

MyClass& MyClass::MyInstance()
{       
    static MyClass myLocalVariable = MyClass(/*parameters*/);
    return myLocalVariable ;
}

当 MyInstance 方法被调用时:

  1. 首先调用 MyClass 的构造函数
  2. 然后是 CopyConstructor
  3. 然后是“return myInstance”行。

myLocalVariable 持有的实例是否可能只是暂时的,以后可能会被销毁?

更新:

由于有些人无法重现我的问题,我在这里添加更多代码。我现在有 3 个具有相同行为的项目(一个是我从单元测试中调用的静态库,另外两个是 Win32 控制台应用程序)

C++ 主要

int _tmain(int argc, _TCHAR* argv[])
{
    MyClass& instance = MyClass::MyInstance();

    return 0;
}

C++ MyClass.h

#pragma once
#include <string>

using namespace std;
class MyClass
{
private:
    string name;

public:
    MyClass(void);
    MyClass(string name);
    MyClass(const MyClass&);

    ~MyClass(void);

    static MyClass& MyInstance();   
};

C++ MyClass.cpp

#include "MyClass.h"
#include <iostream>
using std::cout;

MyClass::MyClass(void)
{
    cout << "Empty Cons\n";
}

MyClass::MyClass(string name)
{
    this->name = name;
    cout << "Parameters Cons\n";
}

MyClass::MyClass(const MyClass& myClass)
{
    name = myClass.name;
    cout << "Copy Cons\n";
}

MyClass::~MyClass(void)
{
    cout << "Destructor\n";
}

MyClass& MyClass::MyInstance()
{       
    cout << "MyInstance\n";
    static MyClass myInstance = MyClass("MyClassName");
    return myInstance;
}

我的输出:

我的实例

参数缺点

复制缺点

析构函数

【问题讨论】:

  • 这在 Visual Studio 中还不是线程安全的。因此,如果您有多个线程调用它,那么您就有了比赛。此外,直接将 C# 设计转换为 C++ 设计通常会给您带来很多内存管理问题。
  • 如果你做了static MyClass myLocalVariable(/*parameters*/);,看看你得到了什么会很有趣。这应该等同于您所拥有的,至少对于基于常规堆栈的变量而言。
  • @SebastianRedl 您对内存问题的看法是正确的!这就是为什么我试图在 C++ 上使用向量和字符串之类的对象来最小化我的问题。原始代码主要用于计算。但是我无法改变对静态实例的需求。我的应用不是多线程的,但 Visual Studio 中的测试可能是多线程的?
  • @TooTone 我刚试过你说的,你只有第一个构造函数被调用。不是副本。
  • @TooTone 我多次调试我的代码,它总是调用两个构造函数。更重要的是,这发生在 2 个不同的程序中。因为当我开始创建问题时,我创建了一个测试项目。让我看看我是否可以添加更多代码以便您重现它。

标签: c++ visual-studio-2012


【解决方案1】:

把变量写成

static MyClass instance;

如果没有参数,或者

static MyClass instance(foo, bar);

如果有的话。或者由于这是 MSVC 2012,可能支持统一初始化语法:

static MyClass instance{/*args here, could be empty*/};

这将就地初始化变量,而不是初始化临时变量并将其复制到目标。 (编译器将被允许省略副本,但显然在您的情况下不会。)

myLocalVariable 持有的实例是否可能只是暂时的

请注意,第一,正确的词是“临时”,第二,myLocalVariable 实例,它不包含一个。除非您明确使用指针或引用,否则 C++ 对象的行为更像 C# 结构而不是类,因为变量不包含引用,它们确实是对象。

【讨论】:

  • 感谢指出变量“是实例”,需要时间来适应 C# 的变化
【解决方案2】:

myLocalVariable 持有的实例是否可能只是暂时的,以后可能会被销毁?

myLocalVariable 是静态的,因此不会被销毁,并且每次调用 MyInstance 时都可用

MyClass& MyClass::MyInstance()
{       
    static MyClass myLocalVariable = MyClass(/*parameters*/);
    return myLocalVariable ;
}

这只会调用 1 个构造函数,它是参数构造函数,因为 myLocalVariable 是通过引用而不是值返回的。

【讨论】:

    猜你喜欢
    • 2017-04-07
    • 2013-10-01
    • 2023-03-13
    • 2021-05-14
    • 1970-01-01
    • 2013-04-25
    • 2012-02-28
    • 1970-01-01
    • 2012-04-29
    相关资源
    最近更新 更多