2013-11-21 41 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

相关问题