2016-01-12 4 views
-1

Теперь у меня есть код ниже:частного наследования и возвращающие ссылки из функций

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

И это работает well.Later добавить некоторый код.

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 &' существует, но недоступна.

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

+4

«И это хорошо работает». Нет, это не так. – curiousguy

+0

В моем vs2010 это действительно работает. И какая ошибка отображается на вашем компьютере? – xingfu0539

+0

* Где * вы получаете сообщение об ошибке? На какой линии? Не могли бы вы отметить это замечанием? Я даже не вижу, чтобы вы использовали указатели использования для «CEnv». –

ответ

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() Функция не является членом или другом; try it:

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

it compiles Теперь.

0

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

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

Или, базовый вариант:

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

Спасибо, и я исправил свой код только сейчас. И теперь мне интересно, почему частное наследование может получить доступ к функциям родительского класса. В 2-м шаблоне кода это недопустимо в функции test(), поэтому я считаю, что это правильно, но в функции Instance() это работает. – xingfu0539

+0

Поскольку производный конструктор всегда имеет доступ к конструктору базового класса. –

+0

@JameyD "производный конструктор всегда имеет доступ к объявлению базового класса" конструктор "? – curiousguy

0

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

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

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^