Почему я получаю Constructor и конструктор копирования, который вызывается здесь? [Дубликат]

0

У меня есть много кода на С#, который я должен написать на С++. У меня мало опыта в С++.

Я использую Visual Studio 2012 для сборки. Проект является Статической библиотекой в ​​С++ (не в С++/CLI).

У меня есть класс со статическим методом со статическим частным членом. Когда я отлаживаю, я вижу, как вызывается как создатель Constructor, так и Copy Constructor. Я не понимаю, почему оба вызываются, я думал, что только один будет. Есть ли способ, которым я могу заставить вызвать только один конструктор?

Это мой код

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

При вызове метода MyInstance:

  • Сначала конструктор MyClass называется
  • Затем CopyConstructor
  • И затем строка "return myInstance".

Возможно ли, что экземпляр, хранящийся myLocalVariable, является только временным и может быть уничтожен позже?

Update:

Так как некоторые люди не могут воспроизвести мою проблему, я добавляю здесь больше кода. У меня есть 3 проекта с одинаковым поведением (один из них - статическая библиотека, которую я вызываю из своих тестов Unit, а остальные 2 - Win32 Console Applications)

С++ Main

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

    return 0;
}

С++ 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();   
};

С++ 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;
}

Мой вывод:

MyInstance

Параметры минус

Копирование минусов

деструктор

  • 0
    Это не поточно-ориентированный в Visual Studio пока. Так что если у вас есть несколько потоков, вызывающих это, у вас есть гонка. Кроме того, прямой перевод проектов C # в проекты C ++ часто приводит к большим проблемам с управлением памятью.
  • 1
    Было бы интересно посмотреть, что вы получили, если бы вы сделали static MyClass myLocalVariable(/*parameters*/); , Это должно быть эквивалентно тому, что у вас есть, по крайней мере для обычных переменных на основе стека.
Показать ещё 5 комментариев
Теги:
visual-studio-2012

2 ответа

3

Просто напишите переменную как

static MyClass instance;

если нет параметров, или

static MyClass instance(foo, bar);

если есть. Или, поскольку это MSVC 2012, может поддерживаться единообразный синтаксис инициализации:

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

Это приведет к инициализации переменной на месте вместо инициализации временного и копирования ее в цель. (Компилятору будет разрешено опустить копию, но, по-видимому, это не так.)

Возможно ли, что экземпляр, хранящийся myLocalVariable, является только временным

Обратите внимание, что во-первых, правильное слово является "временным", а второе, myLocalVariable является экземпляром, оно не удерживает его. Если вы явно не используете указатели или ссылки, объекты С++ ведут себя скорее как структуры С#, чем классы, поскольку переменные не содержат ссылок, они действительно являются объектами.

  • 0
    Спасибо за указание на переменную "is instance", требуется время, чтобы привыкнуть к изменению с C #
1

Возможно ли, что экземпляр, хранящийся myLocalVariable, является только временным и может быть уничтожен позже?

myLocalVariable статичен, поэтому не будет уничтожен и будет доступен каждый раз, когда вы вызываете MyInstance

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

Это вызовет только 1 конструктор, который является конструктором param, поскольку myLocalVariable возвращается по ссылке, а не по значению.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню