C ++有一个嵌套类继承自另一个嵌套类

时间:2013-01-25 02:22:52

标签: c++ oop inheritance nested-class

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

编辑here似乎无法做到这一点。还有其他方法我可以保留这个通用结构并仍然编译吗?

Root.h

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

ROOT.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

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分:1)

您的主要问题是BaseDef是私有的。这意味着其他类(除了Root本身)无法访问BaseDef名称。一种方法是公开BaseDef。或者,您可以创建WinImp的派生类(NixImpRoot)朋友,以便他们可以访问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)。然而,clang(3.1测试)即使在2003模式下也接受这一点。 gcc(4.7.2已测试)接受此(即使在2003模式下),只要派生类嵌套在同一个类中,但如果在类之外则不会。