Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么这段代码不编译?_C++_Class_Gcc_Compiler Errors - Fatal编程技术网

C++ 为什么这段代码不编译?

C++ 为什么这段代码不编译?,c++,class,gcc,compiler-errors,C++,Class,Gcc,Compiler Errors,我遇到了这样的情况: struct Foo { void Barry() { } }; struct Bar : private Foo { template <class F> void Bleh(F Func) { Func(); } }; struct Fooey : public Bar { void Blah() { Foo f; Bar::Bleh(std::bind(&Foo::Barry, &f)); } }; 但是,如果

我遇到了这样的情况:

struct Foo
{
    void Barry() { }
};

struct Bar : private Foo
{
    template <class F> void Bleh(F Func) { Func(); }
};

struct Fooey : public Bar
{
    void Blah() { Foo f; Bar::Bleh(std::bind(&Foo::Barry, &f)); }
};
但是,如果我这样做:

class Fooey;
void DoStuff(Fooey* pThis);

struct Fooey : public Bar
{
    void Blah() { DoStuff(this); }
};

void DoStuff(Fooey* pThis)
{
    Foo f;
    pThis->Bleh(std::bind(&Foo::Barry, &f));
}
它编译得很好。这背后的逻辑是什么

struct Fooey : public Bar
{
    void Blah() { Foo f; Bar::Bleh(std::bind(&Foo::Barry, &f)); }
};
Foo
的名称查找找到
Bar
的基类,该基类不可访问,因为
Bar
是私有继承的

要修复此问题,请完全限定名称:

    void Blah() { ::Foo f; Bar::Bleh(std::bind(&::Foo::Barry, &f)); }

这是名字冲突。对于每个继承的类型,您将在自己的类中获得该名称的成员。要访问实际类型,需要通过其限定名称引用它(在本例中,
::Foo

此功能允许您使用派生类中基类的隐藏或重写成员:

struct X
{
    void Foo();
};

struct Y : public X
{
    void Foo()
    {
        X::Foo(); // calls X's implementation of Foo
    }
};

但这确实意味着,如果你是指
X
,就像在
struct X
中一样,你需要用它的全名来限定它,称它为
::X
,当你用私有继承从
Foo
继承
Bar
时,你将
Foo
的所有成员数据/函数都私有化。因此,当您从
Bar
继承
fooy
时,它无法访问
Foo
的任何成员

有关私有继承的更多详细信息:


这个包含范围“fix”的块还创建了另一个
Foo
(也就是说,Fooey已经通过它与
Bar
的继承拥有了一个
Foo
对象-这是在创建另一个对象并绑定它的
Barry
)。

问题是,在
Foo
或从它派生的任何类中,
Foo
是注入的类名;作用域位于
Foo
内的名称,它在封闭的命名空间中隐藏类的相同名称。在本例中,由于私有继承,无法访问


您可以通过显式引用命名空间中的名称来解决此问题,在本例中为
::Foo
。不幸的是,如果您将类移动到另一个名称空间,则会出现这种情况。

在第一种情况下尝试
&::Foo::Barry
。@MislavBlažević使用Foo.void Blah()的公共继承(或结构的默认公共继承){::Foo f;Bar::Bleh(std::bind(&::Foo::Barry,&f))}修复了这是私有继承与公共继承的问题。与命名冲突无关。@ZacHowland,那么为什么使用
::Foo
而不使用
Foo
呢?此外,我们在哪里使用一个私有继承的成员?这只是因为他正在创建要绑定的
Foo
的第二个实例。他正在使用一个“has a”关系,然后使用composition创建另一个。他试图对一个不同的Foo对象调用一个Foo方法,该对象来自一个(私下)从Foo继承的类,但它不起作用,因为编译器认为他指的是一个私下继承的成员。听起来很像一个名字对我来说是指两种不同的东西。啊,我明白你现在的意思了。
struct X
{
    void Foo();
};

struct Y : public X
{
    void Foo()
    {
        X::Foo(); // calls X's implementation of Foo
    }
};
struct Fooey : public Bar
{
    void Blah() { Foo f; Bar::Bleh(std::bind(&::Foo::Barry, &f)); }
};