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

它运行良好。稍后我添加了一些代码。

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:'type cast':从'CEnv *'到'Env&'的转换存在,但无法访问。

在我看来,显示错误是正确的,因为如果使用私有继承,它就不是一种关系。但是第一个 Code Pattern 运行良好。我想知道为什么?

4

3 回答 3

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

现在它编译

于 2016-01-12T09:34:49.733 回答
0

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

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

或者,参考案例:

static Env& Instance()
{
    static CEnv instance;
    return instance;
}
于 2016-01-12T09:04:52.640 回答
0

私有继承是一种“is-a”关系,除了继承类本身之外,对所有人来说都是秘密。

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

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

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

于 2016-01-12T09:27:51.960 回答