Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/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++_Oop_Inheritance - Fatal编程技术网

C++ 为什么可以';我不能通过继承访问这个方法吗?

C++ 为什么可以';我不能通过继承访问这个方法吗?,c++,oop,inheritance,C++,Oop,Inheritance,我有两个简单的类,希望通过传递int值来访问公共方法stuff。为什么我不能用Bar的一个实例来做呢?它不应该继承公共方法吗。类型暗示给int一个参数,但它不编译 class Foo { public: int a; void stuff(int a){ std::cout << a << std::endl; } }; class Bar : public Foo { protected: void stuff() { std::cout &l

我有两个简单的类,希望通过传递
int
值来访问公共方法
stuff
。为什么我不能用Bar的一个实例来做呢?它不应该继承公共方法吗。类型暗示给
int一个
参数,但它不编译

class Foo
{
public:
    int a;
    void stuff(int a){ std::cout << a << std::endl; }
};

class Bar : public Foo
{
protected:
    void stuff() { std::cout << "hello world"; }
};



void main()
{
    Bar b
    b.stuff(3);
}
class-Foo
{
公众:
INTA;

在C++中,空函数(int a){sd::cOut,当基类中的一个函数与派生类中的一个函数的名称相同时,可以进行名称隐藏。 函数调用过程的各个阶段

  • 名称查找
  • 过载分辨率
  • 访问控制
  • 名称查找在派生类
    Bar
    中找到名称后立即停止查找其他名称。因此,
    Bar::stuff()
    Foo
    中隐藏任何名为
    stuff
    的函数

    在名称查找过程之后

    • 重载解析失败,因为
      条中没有
      填充(int)
    • 即使调用了不带
      int
      参数的
      stuff()
      ,访问控制也会失败,因为
      stuff()
      受到保护

    在查找名称
    stuff
    时,首先找到
    栏中的那一个。找到后,将检查访问权限。由于
    栏::stuff
    受到保护,因此您无法从
    main
    使用它

    根据标准草案:

    10.2成员名称查找[class.Member.lookup]

    1成员名称查找确定类范围(3.3.7)中名称(id表达式)的含义.名称查找可能会导致歧义,在这种情况下,程序的格式不正确。对于id表达式,名称查找从
    this
    的类范围开始;对于限定id,名称查找从嵌套名称说明符的范围开始。名称查找在访问控制之前进行(3.4,第11条)

    或者,您可以使用技巧访问任何受保护的:)

    void main()
    {
    b栏;
    类BarAccess:public Bar{friend void main();}
    BarAccess*ba=重新解释铸件(&b);
    文学士->材料(3);
    ba->stuff();
    }
    
    因为
    Bar::stuff
    隐藏
    Foo::stuff
    (执行重载解析时,仅名称重要,参数被忽略)

    您可以:

    • 使用
    声明将其带入sope
  • 或者,明确限定调用,例如
    b.Foo::stuff(3);
  • 注意

    • main()
      必须返回
      int


    试试b.Foo::stuff(3);
    。调用基类成员函数时,必须显式解析作用域,因为派生类的受保护成员函数隐藏了作用域,因为它们具有相同的名称。这就解决了问题,谢谢。这是否意味着所有继承的对象都带有基类的隐藏成员,并且其成员/方法必须e通过实例和静态方法调用的交叉进行访问?@RaymondChen没有进行强制转换。我不会说它们携带基类的隐藏成员,而是基类的对象。这很有趣,但有点道理-谢谢!我认为使用诸如public/protected/private之类的访问修饰符的全部目的是设置请查看我的更新答案。@user3791372:关键是要设置可见性,使
    条中的
    内容不能被使用。这是一些“技巧”;)无意冒犯,但我不同意这个技巧。你放弃了封装的意义。谢谢,这很好地结束了一切。为什么必须
    main
    返回一个int?在c++11中,将main声明为void是一种不好的形式吗?它与c++11无关,请参阅了解良好-谢谢
    b.Foo::stuff(3);
    
    void main()
    {
        Bar b;
        class BarAccess : public Bar { friend void main(); }
        BarAccess * ba = reinterpret_cast<BarAccess *>(&b);
        ba->stuff(3);
        ba->stuff();
    }
    
    #include <iostream>
    
    class Foo
    {
    public:
        int a;
        void stuff(int a){ std::cout << a << std::endl; }
    };
    
    class Bar : public Foo
    {
    public:
        using Foo::stuff;
    protected:
        void stuff() { std::cout << "hello world"; }
    };
    
    int main()
    {
        Bar b;
        b.stuff(3);
    }
    
    int main()
    {
        Bar b;
        b.Foo::stuff(3);
    }