0

我正在编写一个跨平台的类层次结构,并希望将依赖于平台的实现保留在它们自己的类中(而不是使用一个类#ifdefs)。这是我到目前为止所拥有的,但编译器抱怨这BaseDef是私有的。对于如何在编译它的同时保持这个基本结构的任何帮助将不胜感激:-)

编辑:这里看来这是不可能的。还有什么其他方法可以保持这个一般结构并仍然编译吗?

根目录

class Root {
    private:
        class BaseDef {
            virtual void foo() = 0;
            virtual void bar() = 0;
        };

        #ifdef _WIN32
        class WinImp;
        #else
        class NixImp;
        #endif

        BaseDef* imp;

        BaseDef* getImp();

    public:
        Root() : imp(getImp()) {}
        void foo();
        void bar();
};

根.cpp

#include "Root.h"
void Root::foo() {
    imp->foo();
}

void Root::bar() {
    imp->bar();
}

WinImp.h

#ifdef _WIN32
#include "Root.h"
class WinImp : public Root::BaseDef {
    public:
        void foo();
        void bar();
};
#endif

WinImp.cpp

#include "WinImp.h"
#ifdef _WIN32
    Root::WinImp::foo() {

    }

    Root::WinImp::bar() {

    }

    Root::BaseDef* Root::getImp() {
        return new Root::WinImp();
    }
#endif
4

2 回答 2

1

它抱怨的BaseDefprivate...

class Root {
    private:
        class BaseDef {
            virtual void foo() = 0;
            virtual void bar() = 0;
        };

所以公开...

class Root {
    public:
        class BaseDef {
            virtual void foo() = 0;
            virtual void bar() = 0;
        };

脚注:

你试图避免#ifdef,所以摆脱这个:

#ifdef _WIN32
class WinImp;
#else
class NixImp;
#endif

相反,只需使用一个类:

class Imp;
于 2013-01-25T02:25:16.237 回答
1

你的主要问题是这BaseDef是私人的。这意味着其他类(除了 Root 本身)无法访问该BaseDef名称。一种方法是BaseDef公开。或者,您可以使派生类 (WinImpNixImp) 成为朋友,Root以便他们可以访问该BaseDef名称。此外Root无法访问 的成员,BaseDef因此他们需要公开或成为Root的朋友BaseDef

class Root {
private:
  class BaseDef {
  public:
    // These need to be public so that Root can see them or Root needs to be a friend. 
    //Nothing else can see BaseDef though so this is safe.
    virtual void foo() = 0;
    virtual void bar() = 0;
  };

  class WinImp; // Forward declare the classes
  friend class WinImp; // And then make them friends
  class NixImp;
  friend class NixImp;

  BaseDef* imp;

  BaseDef* getImp();

public:
  Root() : imp(getImp()) {}
  void foo();
  void bar();
};

void Root::foo() {
  imp->foo();
}

void Root::bar() {
  imp->bar();
}

// Since this is a nested class i made it Root::WinImp
class Root::WinImp : public Root::BaseDef {
public:
  void foo();
  void bar();
};

void Root::WinImp::foo() {}

void Root::WinImp::bar() {}

Root::BaseDef* Root::getImp() {
  return new WinImp();
}

根据 2003 标准 (11.4.p2),此方法是不允许的,但在 C++11(相同示例)中,它是明确允许的 (11.3.p2)。但是,即使在 2003 模式下,clang(经过 3.1 测试)也接受了这一点。gcc(4.7.2 测试)接受这一点(即使在 2003 模式下),只要派生类嵌套在同一个类内,但如果在类外则不会。

于 2013-01-25T03:22:30.867 回答