函数

时间:2016-01-12 08:42:43

标签: c++ private-inheritance

现在我有以下代码:

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&'存在,但无法访问。

在我看来,显示错误是正确的,因为如果使用私人遗嘱,它不是一种关系。 但第一个代码模式效果很好。 我想知道为什么?

3 个答案:

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

答案 1 :(得分:0)

您的Instance()方法已损坏,您应该只有1 static个对象:

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

或者,参考案例:

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

答案 2 :(得分:0)

私有继承是一种“is-a”关系,除了继承类本身之外,它是每个人的秘密。

CEnv类中,继承是“已知的”(如果不允许继承类知道它,则私有继承将是无用的)。

因此,CEnv*中从Env*CEnv::Instance的转换是有效的,因为它是进行转换的CEnv

test函数不是CEnv的成员,因此从其角度来看,不允许转换。