oop — C ++ имеет один вложенный класс, наследуемый от другого вложенного класса

Я пишу кроссплатформенную иерархию классов и хочу сохранить зависимые от платформы реализации в своем собственном классе (в отличие от наличия одного класса с #ifdefs). Это то, что я до сих пор, но компилятор жалуется, что BaseDef это личное. Любая помощь с тем, как я мог бы сохранить эту базовую структуру во время компиляции, будет принята с благодарностью 🙂

Редактировать: Казалось бы из Вот что это невозможно. Любой другой способ, которым я мог бы сохранить эту общую структуру и все еще компилировать?

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

0

Решение

Ваша главная проблема в том, что BaseDef это личное. Это означает, что другие классы (кроме самого Root) не могут получить доступ к BaseDef название. Один из способов сделать BaseDef общественности. В качестве альтернативы вы можете сделать производные классы (WinImp а также NixImp) друзья 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). Однако clang (протестированный 3.1) принимает это даже в режиме 2003. gcc (проверено 4.7.2) принимает это (даже в режиме 2003), если производные классы вложены в один и тот же класс, но не если он находится вне класса.

1

Другие решения

Жалуется что BaseDef является private

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

По вопросам рекламы [email protected]