c++中的overload、overwrite、override

作为初学者,本文只从语法和简单的使用角度对overload、overwrite、override进行了区分,不曾涉及原理,记录下来以供查阅。

1.verload(重载)

1.1 基本要求:

c++中的重载需要满足以下几个要求:

  • 相同的作用域
  • 函数名相同,参数列表不同,与返回值类型无关

例如:

void Fun()
{

}
void Fun(int n)
{

}
int Fun()       //只是返回类型不同,不能构成重载
{

}

注意:同名的函数必须在相同的作用域内才构成重载。

1.2 类中成员函数

类中的普通成员函数构成重载要满足上面的基本要求,另外:

  • 成员函数的名称,参数列表相同时,non-const成员函数与const成员函数可以构成重载;
  • 成员函数的名称,参数列表不同时,non-const成员函数与const成员函数可以构成重载;
  • 成员函数的名称,参数列表相同时,non-static成员函数与static成员函数不能构成重载;
  • 成员函数的名称,参数列表不同时,non-static成员函数与static成员函数可以构成重载

例如:

class Test
{
public:
    void Fun();
    void Fun() const;
    static void Fun(int n);
};

void Test::Fun() 
{
    cout << "Test::Fun() ..." << endl;
}
void Test::Fun() const
{
    cout << "Test::Fun() const ..." << endl;
}
/*
void Test::Fun()
{
    cout << "static Fun() ..." << endl;
}
*/
void Test::Fun(int n)
{
    cout << "static Fun(int n) ..." << endl;
}

注意:const成员函数在类中声明时带const关键字,在类外定义时也要加const关键字;static成员函数在类中声明时带const关键字,在类外定义时则不需要加static关键字。


2.override(覆盖)

override和overwrite都是发生在基类与派生类函数之间,override需要满足以下几个要求:

  • 不同的作用域,基类与派生类
  • 虚函数,基类的成员函数带virtual关键字
  • 基类成员函数与派生类成员函数名称相同,参数列表也相同

例如:

class Base
{
public:
    virtual void Fun();
};

void Base::Fun()
{
    cout << "Base::Fun ..." << endl;
}
class Derived :public Base
{
public:
    void Fun();
};
void Derived::Fun()
{
    cout << "Derived::Fun ..." << endl;
}

int main()
{
    Base* pb = new Base;
    Derived d;
    pb = &d;//基类指针指向派生类对象
    pb->Fun(); //调用派生类的函数实现多态 
    pb->Base::Fun();

    return 0;
}

在这个例子中要注意的是,基类的virtual void Fun();与派生类的void Fun();形成多态,所以可以通过基类指针访问派生类的函数


3.overwrite(重写)

overwrite需要满足以下几个要求:

  • 不同的作用域,基类与派生类
  • 基类成员函数不带virtual关键字,基类成员函数与派生类成员函数名称相同,参数列表相同与不相同都可以
  • 基类成员函数带virtual关键字,但基类成员函数与派生类成员函数名称相同,参数列表不相同

例如:基类成员函数带virtual关键字,但基类成员函数与派生类成员函数名称相同,参数列表不相同时:

class Base
{
public:
    virtual void Fun();
};

void Base::Fun()
{
    cout << "Base::Fun ..." << endl;
}
class Derived :public Base
{
public:
    void Fun(int n);
};
void Derived::Fun(int n)
{
    cout << "Derived::Fun ..." << endl;
}
int main()
{
    Base* pb = new Base;
    Derived d;
    pb = &d;
    pb->Fun();
    //pb->Fun(2);   Error,没有形成多态,不能调用派生类的函数
    
    d.Fun(3);
    //d.Fun();  //Error,基类中的Fun()被派生类重写,隐藏起来
    d.Base::Fun();//通过作用域运算符调用基类函数

    return 0;
}

在这个例子中要注意的是,基类的virtual void Fun();与派生类的void Fun(int n);没有形成多态,所以不能通过基类指针访问派生类的函数

再例如:基类成员函数不带virtual关键字,基类成员函数与派生类成员函数名称相同,参数列表相同与不相同时

class Base
{
public:
    void Fun();
};

void Base::Fun()
{
    cout << "Base::Fun ..." << endl;
}
class Derived :public Base
{
public:
    void Fun(int n);
};
void Derived::Fun(int n)
{
    cout << "Derived::Fun ..." << endl;
}

int main()
{
    Derived d;

    d.Fun(3);
    //d.Fun();  //Error,基类中的Fun()被派生类重写,隐藏起来
    d.Base::Fun();

    return 0;
}
class Base
{
public:
    void Fun();
};

void Base::Fun()
{
    cout << "Base::Fun ..." << endl;
}
class Derived :public Base
{
public:
    void Fun();
};
void Derived::Fun()
{
    cout << "Derived::Fun ..." << endl;
}

int main()
{
    Derived d;

    d.Fun();//调用派生类的函数,基类函数被重写隐藏
    d.Base::Fun();

    return 0;
}

通过对overwrite的3个例子实现,发现overwrite会将基类的函数隐藏起来,派生类对这个函数进行重写,通过派生类对象不能直接调用该函数;基类指针指向派生类对象时,只能调用基类的函数,不能调用派生类函数

posted on 2018-01-23 20:46 ccilery 阅读() 评论() 编辑 收藏

版权声明:本文为ccilery原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/ccilery/p/8337794.html