2013-11-21 43 views
3

我有很多必須用C++編寫的C#代碼。我沒有太多的C++經驗。什麼是C++中的C#靜態實例的等價物?

我正在使用Visual Studio 2012來構建。該項目是一個靜態庫,位於C++(不在C++/CLI中)

在C#代碼不存在用於一些靜態實例創建了一個類

C#

namespace MyNamespace 
{ 
     public class MyClass 
     { 
      //Class Code 

     static public MyClass Instance1 = new MyClass(/*parameters*/); 
     static public MyClass Instance2 = new MyClass(/*other parameters*/); 

我需要做用C類似++,到目前爲止我

C++

namespace MyNamespace 
{ 
    class MyClass 
    { 
     //Class Code 

    }//end of class 

    static MyClass& Instance1 = MyClass(/*parameters*/); 
    static MyClass& Instance2 = MyClass(/*other parameters*/); 

}//end of Namespace 

但是,從我讀的這個不完全相同,通過添加單詞「靜態」我所做的是我的Instance1和Instance2只在當前文件的範圍內可見。它是否正確?

所以我不想要一堆Instance1,我只想在整個程序中使用一個。 我讀到,而不是使用靜態,我可以使用extern,它告訴編譯器該變量的定義是在另一個文件,因此我會結束只有一個Instance1和Instance2的實例,而不是多個。

所以,我想:

C++ MyClass.h

extern MyClass& Instance1; 
extern MyClass& Instance2; 

C++ MyClass.cpp

MyClass& Instance1 = MyClass(/*parameters*/); 
MyClass& Instance2 = MyClass(/*other parameters*/); 

這建立就好了,但是當我嘗試運行我的測試,他們會拋出一個錯誤:

Failed to set up the execution context to run the test 

使用的extern我的測試之前跑就好了,但是當我添加它,他們將無法正常工作。這導致我相信我沒有正確地聲明事情,或者Visual Studio 2012不能正確支持某些功能?

回答

4

static根據使用它的地方在C++中有不同的含義。當與一個變量聲明一起使用時,它意味着你在想什麼:對於變量沒有鏈接,它只對聲明的文件是可用的,或者甚至如果是局部變量,只有一個副本(好方法來聲明局部變量,它們應該在使用位置附近是靜態的)。

在類聲明中,靜態意味着與C#中的相同,不同之處在於您必須有一個實際聲明靜態變量的源文件(或者在方法中聲明它爲static),因爲此static變量必須有空間保留的地方。這可以通過多種方式來完成,例如:

static MyClass& instance() { 
    static MyClass realInstance; 
    return realInstance; 
} 

通過這種方式,你可以看到使用static的兩種方式:一種是告訴大家,instance()方法static(附着在類的命名空間,而不是一個單個實例),並且聲明一個靜態變量,即使它是局部變量,它也只有一個本身的副本。

+0

有一個問題,你做靜態MyClass realInstance,有哪裏我應該初始化我的istance沒有? – Dzyann

+0

是的,你的意思是'靜態MyClass realInstance(參數);'。 – Jack

+0

如果您在cpp中創建實例,但在Instance()方法之外創建實例?它會是一樣的嗎? – Dzyann

2

不,static意味着你想要它的意思是當用於聲明類成員

當用於聲明全局非成員變量時,它具有「僅在當前文件中」的含義。

static是C++中一個非常通用的詞。

但是,你的第一次嘗試是正確的(除了&。刪除。你不想存儲一個對立即超出範圍並被破壞的對象的引用。你想存儲對象本身)

+0

我很困惑,你是說,通過&我真的保存一個靜態引用?所以對象本身可能會被破壞? – Dzyann

+1

是的,你指定的靜態成員應該是一個參考 – jalf

+0

從我的理解,你的答案似乎與其他答案相矛盾,他們說,我將以我的代碼的方式結束Instance1的幾個實例,我應該創建一個返回Instance1的函數,你不同意嗎? – Dzyann

0

靜態變量不能在您聲明它們的文件外面「看到」。但是,如果您需要在其他文件中使用該變量,則可以在返回該靜態變量的類中編寫靜態函數。

1

在C++中,代碼被稱爲「單位翻譯」的單位分開。簡單地說,一個單位的換算是一個.cpp文件。

「靜態」變量是以定義的翻譯單位存在的變量。所以,如果您有:

Static.h

static int myStatic = 0; 

Static1.cpp

#include "Static.h" 

Static2.cpp

#include "Static.h" 

你會實際上有兩個靜態變量myStatic,每個翻譯單元一個副本。作爲一個經驗法則,永遠不要在頭文件中聲明靜態變量,除非它是一個模板類(我真的不知道爲什麼它仍然不是一個警告)。 .h文件實際上沒有編制,他們的代碼件包括到cpp文件(因此關鍵字#include

要做到這一點「規範地」,你需要做的是這樣的:

Static.h

class MyClass { 
public: 
    static MyClass& GetInstance1(); 
    static MyClass& GetInstance2(); // static method means just same as in C# 
// Other stuff 
} 

Static.cpp

#include "Static.h" 

static MyClass instance1(/* parameters */); 
static MyClass instance2(/* other parameters */); 

MyClass& MyClass::GetInstance1() {return instance1;} 
MyClass& MyClass::GetInstance2() {return instance2;} 

有點冗長,但在某些情況下比C#更靈活。

用法:

SomeOtherFile.cpp

#include "Static.h" 

MyClass::GetInstance1().DoSomeAction(); 

我相信,你的測試將後正常運行。

+0

所以我不應該直接在命名空間中聲明靜態事物?在我的代碼中,我將它們聲明在.h文件中,但在名稱空間中不是類本身 – Dzyann

+0

問題不在於名稱空間,而在於翻譯單元。確保''.cpp'文件中聲明瞭'static something',以及在'.h'文件中訪問它的方法。如果你在你的'.h'中聲明它們,那麼''include''中的每個'.cpp'都將擁有你自己的「不太靜態」變量的副本。 – DarkWanderer

相關問題