Частное наследование и возврат ссылок из функций

Теперь у меня есть код ниже:

class Env
{
public:
int ra(){ return a;}
int rb(){ return b;}
private:
int a;
int b;
};class CEnv: private Env
{
public:
static Env* Instance()
{
CEnv* pEnv = new CEnv;
return pEnv;
}

};int _tmain(int argc, _TCHAR* argv[])
{

Env* pEnv = CEnv::Instance();
pEnv->ra();

return 0;
}

И это работает хорошо. Позже я добавлю немного кода.

class Env
{
public:
int ra(){ return a;}
int rb(){ return b;}
private:
int a;
int b;
};class CEnv: private Env
{
public:
static Env* Instance()
{
CEnv* pEnv = new CEnv;
return pEnv;
}

};

Env* test()
{
CEnv *p = new CEnv;
return p;
}

int _tmain(int argc, _TCHAR* argv[])
{

Env* pEnv = CEnv::Instance();
pEnv->ra();

return 0;
}

Тогда VS2010 сообщит об ошибке компилятора:
ошибка C2243: «приведение типа»: преобразование из «CEnv *» в «Env» &’существует, но недоступно.

На мой взгляд, правильно показывать ошибку, потому что это не как отношения, если используется личное наследство.
Но первый шаблон кода работает хорошо.
И мне интересно, почему?

-1

Решение

Если вы замените частное наследование частным членом, вы получите точно такой же результат:

class Env
{ /* whatever */
};

class CEnv{
private:
Env m;

public:
static Env *Instance()
{
CEnv *pEnv = new CEnv; /* memory leak */
return &pEnv->m;
}
};

(Забудьте об утечке памяти, так как это только для иллюстрации.)

Здесь член доступен так как Instance() является членом класса.

С функцией, не являющейся членом:

Env *test()
{
CEnv *p = new CEnv;
return &p->m;
}

функция test() не член или друг; попытайся :

prog.cpp: In function 'Env* test()':
prog.cpp:7:13: error: 'Env CEnv::m' is private
Env m;
^
prog.cpp:20:20: error: within this context
return &p->m;
^

Сделайте это другом, если вы должны:

class CEnv2 {
private:
Env m;
friend Env *::test2();
};

Env *test2()
{
CEnv2 *p = new CEnv2;
return &p->m;
}

Сейчас это компилируется.

1

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

Ваш Instance() метод сломан, вы должны иметь только 1 static объект:

static Env* Instance()
{
static CEnv instance;
return &instance;
}

Или ссылочный случай:

static Env& Instance()
{
static CEnv instance;
return instance;
}
0

Частное наследование — это отношение «есть», которое является секретом для всех, кроме самого наследующего класса.

Внутри вашего CEnv класс, наследование «известно» (частное наследование было бы в основном бесполезным, если бы наследующему классу было запрещено знать об этом).

Таким образом, преобразование из CEnv* в Env* в CEnv::Instance действителен, так как это CEnv это делает преобразование.

test функция не является членом CEnvпоэтому, с его точки зрения, конвертация не разрешена.

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