没有私人会员的集体声明

时间:2012-01-01 18:07:52

标签: c++

所以,我愿意像我那样构建我的项目:

ClassA.cpp:

class ClassA {
public:
    static ClassA* create() {
        return new ClassA();
    }
    void methodA() {
        // stuff here
    }
    void methodB() {
        // more stuff here
    }
private:
    ClassA() {
    }
    void privateMethodOne() {
        //yadda yadda
    }
    int attributeA;
    char attributeB;
};

ClassA.hpp:

class ClassA {
public:
    ClassA* create();
    void methodA();
    void methodB();
private:
    ClassA();
};

我将只使用指针工作,我想知道这种方法是否会在将来产生错误。我想知道这里是否存在陷阱。假设.hpp是自动生成的,因此除了私有成员之外,它们具有完全相同的成员。

3 个答案:

答案 0 :(得分:6)

此方法无效。 C ++有one definition rule。有关完整的详细信息,请参阅C ++ 03第3.2节,但这里是维基百科的摘要(突出显示是我的):

  

简而言之,ODR声明:

     
      
  1. 在任何翻译单元中,模板,类型,函数或对象只能有一个定义。其中一些可以有任意数量的声明。定义提供了一个实例。
  2.   
  3. 在整个程序中,对象或非内联函数不能有多个定义;如果使用了对象或函数,则它必须只有一个定义。您可以声明从未使用过的对象或函数,在这种情况下,您不必提供定义。在任何情况下都不能有多个定义。
  4.   
  5. 可以在多个翻译单元中定义某些内容,例如类型,模板和外部内联函数。对于给定的实体,每个定义必须相同。不同翻译单元中的非外部对象和函数是不同的实体,即使它们的名称和类型相同。
  6.   

您可能正在寻找PIMPL idiom,这是一种从公共接口“隐藏”私有成员的方式(即公共头文件)。

答案 1 :(得分:1)

OP表示希望:

“...隐藏私有属性,这样如果属性数量发生变化,您就不必部署新标题”

然后我会通过从实现中分离接口来解决这个问题。您公开界面并隐藏实现。

您可以向需要使用该类的人公开的是一个瘦接口而不是类声明。 C ++中的精简界面最好用纯虚函数来描述。您还将公开一个函数,该函数返回实现此接口的对象。

首先公开API的头文件。这是该服务的所有用户都会看到:

struct Interface1 {        
    virtual ~Interface1() {}
    virtual void methodA()=0;
};

Interface1* createInstanceOfInterface1();

然后在您的服务用户看不到的文件中我们有实现:

class Interface1Impl : public Interface1 {
    private:
        int nTopSecretMemberVar;
    public:
        virtual void methodA() {
          //implement it
        }
};

Interface1* createInstanceOfInterface1() {
    return new Interface1Impl();
}

人们使用您的API使用未公开实施细节的服务,如下所示:

void test() {
   Interface1* p = createInstanceOfInterface1();
   p->methodA();
}

当将这些服务的实现放在可以在运行时插入和播放的DLL或共享库中时,这将成为一种特别有价值的实践。它带来了许多好处。

答案 2 :(得分:0)

这实际上是A类的双重定义