Effective C ++ Item 33: Inheritance of the object-oriented (avoid cover inherited name)

First, the hidden variable usage rules

  • When there is the same global and local variables, the local scope, global scope variable names are hidden, priority use of local variables
  • E.g:
int x; //全局变量

void someFunc()
{
    double x; //局部变量
    std::cin >> x; //局部变量赋值
]

Second, the succession of hiding and rewrite (cover)

  • When a variable group defined in the class / function member, the derived class also defines the same name, the variables of the base class / function will be hidden member in a derived class

Case presentation

class Base
{
private:
    int x;
public:
    virtual void mf1() = 0;
    virtual void mf2();
    void mf3();
};

class Derived :public Base
{
public:
    virtual void mf1(); //重写(覆盖)
    void mf4(){
        fm2(); //调用基类中的fm2
    }
};
  • Relationship of the above categories as follows:

  • Derived in the fm4 () function call fm2 () function, for fm2 () function search order is as follows:
    • First look at fm4 () function, if not the next step
    • Then in the Derived class, if not the next step
    • And then look in the base class Base in (to find it call the base class Base)
    • Assuming Base has not found, then look in the namespace Base is located in; if there is no scope in the Global Search continues

Third, all the base class hiding

  • If the base class contains a series of overloaded functions, as long as the derived class defines a function with the same name as the base class, then all overloaded functions in the base class for the derived class is all hidden (even if the parameter list is inconsistent)
  • The reason design rule: to prevent overloads you incidentally inherited from distant base class when creating a new derived class within the program library or application framework

Case presentation

class Base
{
private:
    int x;
public:
    virtual void mf1() = 0;
    virtual void mf1(int);
    virtual void mf2();
    void mf3();
    void mf3(double);
};

class Derived :public Base
{
public:
    virtual void mf1(); //基类中的所有mf1()都被隐藏
    void mf3();         //基类中的所有fm3()都被隐藏
    void mf4();
};
  • There are now calling code below:
Derived d;
int x;

d.mf1();  //正确
d.mf1(x); //错误,Base::fm1(int)被隐藏了

d.mf2();  //正确

d.mf3();  //正确
d.mf3(x); //错误,Base::mf3(double)被隐藏了

Increase the use of the base class member function by using statement

  • Sometimes the hide may violate is-a relationship between the base class and the derived class (the base class because we want some acts can also be used in a derived class). Therefore, we can use an expression using declaration cancel this hidden import function behavior of the base class in a derived class
  • NOTE: When using declaration, when the derived class using the different access modes (public, protected, private), then the base class to the derived class belonging to the access mode
  • Case presentation:

class Base
{
private:
    int x;
public:
    virtual void mf1() = 0;
    virtual void mf1(int);
    virtual void mf2();
    void mf3();
    void mf3(double);
};

class Derived :public Base
{
public:
    using Base::mf1; //Base所有版本的mf1函数在派生类作用域都可见
    using Base::mf3; //Base所有版本的mf3函数在派生类作用域都可见

    virtual void mf1(); //重写mf1()函数
    void mf3();         //隐藏了mf1(),但是mf3(double)没有隐藏
    void mf4();
};
  • There are now calling code below:
Derived d;
int x;

d.mf1();  //正确,调用Derived::mf1()
d.mf1(x); //正确,调用Base::mf1(int)

d.mf2();  //正确,调用Derived::mf2()

d.mf3();  //正确,调用Derived::mf3()
d.mf3(x); //正确,调用Base::mf3(double)

Use care function

  • Sometimes derived classes in a private manner inherited from the base class , then all the contents of the base class are all invisible to the derived class is
  • Even private, a derived class may be rewritten (overwritten) members of the base class or hide / function . E.g:
class Base
{
public:
    void mf1() {}
    void mf1(int) {}
};

class Derived :private Base
{
public:
    void mf1() {} //隐藏了基类的mf1()
};

int main()
{
    Derived d;
    int x;

    d.mf1();  //正确,使用Derived::mf1()
    d.mf1(x); //错误

    return 0;
}
  • At this point, we can also use the using statement to all the heavy-duty versions of the base class are visible in the derived class. E.g:
class Base
{
public:
    void mf1() {}
    void mf1(int) {}
};

class Derived :private Base
{
public:
    using Base::mf1; //使Base中的所有mf1版本在派生类作用域中都可见
    void mf1() {}    //隐藏Base::mf1()
};

int main()
{
    Derived d;
    int x;

    d.mf1();  //正确,使用Derived::mf1()
    d.mf1(x); //正确,使用Base::mf1(int)

    return 0;
}
  • Of course, in some cases, we do not want all the overloaded versions of a base class are visible in a derived class, you can design a care-yourself function . E.g:
class Base
{
public:
    virtual void mf1() = 0;
    virtual void mf1(int);
};

class Derived :private Base
{
public:
    //这是一个转交函数
    virtual void mf1() {
        Base::mf1(); //调用基类的mf1()函数
    }
};

int main()
{
    Derived d;
    int x;

    d.mf1();  //正确,虽然调用的是Derived::mf1(),但是本质上调用的是Base::mf()
    d.mf1(x); //错误,Base::mf(double)被隐藏了

    return 0;
}

 

IV Summary

Released 1504 original articles · won praise 1063 · Views 430,000 +

Guess you like

Origin blog.csdn.net/qq_41453285/article/details/104760199