精华内容
下载资源
问答
  • C++_重载、重写和重定义的区别

    万次阅读 多人点赞 2015-05-08 18:37:06
    相信看到这个标题头就晕了,其实将他们彼此放到一起来看,就会比较清晰辨认了。 重载:函数名相同,函数参数个数、参数类型或参数顺序三者中...重定义:也叫做隐藏,子类重新定义父类中有相同名称非虚函数( ...

    参考博客:http://blog.sina.com.cn/s/blog_8ddc5c2e01013hbd.html

    相信看到这个标题头就晕了,其实将他们彼此放到一起来看,就会比较清晰辨认了。

    重载:函数名相同,函数的参数个数、参数类型或参数顺序三者中必须至少有一种不同。函数返回值的类型可以相同,也可以不相同。发生在一个类内部,不能跨作用域。

    重定义:也叫做隐藏,子类重新定义父类中有相同名称的非虚函数 ( 参数列表可以不同 ) ,指派生类的函数屏蔽了与其同名的基类函数。可以理解成发生在继承中的重载。

    重写:也叫做覆盖,一般发生在子类和父类继承关系之间。子类重新定义父类中有相同名称和参数的虚函数。(override)

     

    如果一个派生类,存在重定义的函数,那么,这个类将会隐藏其父类的方法,除非你在调用的时候,强制转换为父类类型,才能调用到父类方法。否则试图对子类和父类做类似重载的调用是不能成功的。 

     

    重写需要注意:

    1、 被重写的函数不能是static的。必须是virtual的

    2 、重写函数必须有相同的类型,名称和参数列表

    3 、重写函数的访问修饰符可以不同。

     

    重定义规则如下:

       a 、如果派生类的函数和基类的函数同名,但是参数不同,此时,不管有无virtual,基类的函数被隐藏。

       b 、如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有vitual关键字,此时,基类的函数被隐藏(如果相同有Virtual就是重写覆盖了)。

    #include<iostream>
    
    using namespace std;
    
    class Animal
    {
    public:
        void func1(int tmp)
        {
            cout << "I'm an animal -" << tmp << endl;
        }
    
        void func1(const char *s)//函数的重载
        {
            cout << "I'm an animal func1 -" << s << endl;
        }
    
        virtual void func2(int tmp)
        {
            cout << "I'm virtual animal func2 -" << tmp << endl;
        }
    
        void func3(int tmp)
        {
            cout << "I'm an animal func3 -" << tmp << endl;
        }
    };
    
    class Fish :public Animal
    {
    public:
        void func1()//函数的重定义 会隐藏父类同名方法
        {
            cout << "I'm a fish func1" << endl;
        }
    
        void func2(int tmp) //函数的重写, 覆盖父类的方法 override
        {
            cout << "I'm a fish func2 -" << tmp << endl;
        }
    
        void func3(int tmp) { //函数的重定义 会隐藏父类同名方法
            cout << "I'm a fish func3 -" << tmp << endl;
        }
    };
    
    int main()
    {
        Fish fi;
        Animal an;
    
        fi.func1();
        // 由于是重定义 父类的方法已经被隐藏 
        // 需要显示声明,重载不能跨作用域
        fi.Animal::func1(1);
        dynamic_cast<Animal *>(&fi)->func1(11); // 强转之后即可调用到父类被隐藏的方法
        dynamic_cast<Animal *>(&fi)->func1("hello world"); // 强转之后即可调用到父类被隐藏的方法
        fi.func2(2);	// 调用子类
        dynamic_cast<Animal *>(&fi)->func2(22); // 调用"子类方法"(因为是虚函数,会被子类覆盖)
        dynamic_cast<Animal *>(&fi)->func3(222); // 调用父类
        fi.func3(2222);	// 调用子类
    
        cout << endl << " ************ " << endl;
        an.func1(1);
        an.func1("I'm an animal");
        an.func2(1);
        system("pause");
        return 0;
    }
    
    


    运行结果如下:

     

     
    展开全文
  • 函数重载是指在一个类中声明多个名称相同但参数列表不同函数,这些参数可能个数或顺序,类型不同,但是不能靠返回类型来判断。特征是: (1)相同范围(在同一个作用域中); (2)函数名字相同; (3)...

    本文转自http://m.blog.csdn.net/article/details?id=48496593

    1.函数重载(overload)
    函数重载是指在一个类中声明多个名称相同但参数列表不同的函数,这些的参数可能个数或顺序,类型不同,但是不能靠返回类型来判断。特征是:
    (1)相同的范围(在同一个作用域中);
    (2)函数名字相同;
    (3)参数不同;
    (4)virtual 关键字可有可无(注:函数重载与有无virtual修饰无关);
    (5)返回值可以不同;

    2.函数重写(也称为覆盖 override)
    函数重写是指子类重新定义基类的虚函数。特征是:
    (1)不在同一个作用域(分别位于派生类与基类);
    (2)函数名字相同;
    (3)参数相同;
    (4)基类函数必须有 virtual 关键字,不能有 static 。
    (5)返回值相同,否则报错;
    (6)重写函数的访问修饰符可以不同;

    3.重定义(也称隐藏)
    (1)不在同一个作用域(分别位于派生类与基类) ;
    (2)函数名字相同;
    (3)返回值可以不同;
    (4)参数不同。此时,不论有无 virtual 关键字,基类的函数将被隐藏(注意别与重载以及覆盖混淆);
    (5)参数相同,但是基类函数没有 virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆);

    #include <iostream>
    using namespace std;
    
    class Base
    {
    public:
    	// =========================================================================
    	//  子类和父类返回值参数相同,函数名相同,有/无virtual关键字
    	// =========================================================================
    	
    	//	若无virtual关键字,则在子类中声明与父类同名的方法,从而覆盖了父类的方法(函数重定义)
    	void a() 
    	{
    		cout << "Base::a()" << endl;
    	};
    
    	// 若有virtual关键字,即为虚函数。由对象的类型决定调用哪个函数(多态,函数重写override)。
    	virtual void b()
    	{
    		cout << "Base::b()" << endl;
    	}
    
    	// =========================================================================
    	//  子类和父类返回值参数不同,函数名相同,有/无virtual关键字 
    	// =========================================================================
    
    	// 若无virtual关键字,父类的同名成员被隐藏。
    	void d(int x)
    	{
    		cout << "Base::d() x = " << x << endl;
    	}
    
    	// 若有virtual关键字,父类的同名成员同样被隐藏。
    	virtual void e(int x)
    	{
    		cout << "Base::e() x = " << x << endl;
    	}
    
    	// =========================================================================
    	//  子类和父类返回值参数相同,函数名相同,函数返回值不同,有/无virtual关键字
    	// =========================================================================
    
    	// 若无virtual关键字(函数重写,这种情况不属于“函数重载”范畴)
    	void f()
    	{
    		cout << "void Base::f()" << endl;
    	}
    
    	// 若有virtual关键字 (报错)
    	virtual void g()
    	{
    		cout << "virtual void Base::g()" << endl;
    	}
    };
    
    class Derived : public Base
    {
    public:
    	// =========================================================================
    	//  子类和父类返回值参数相同,函数名相同,有/无virtual关键字
    	// =========================================================================
    
    	//	覆盖了父类同名方法(函数重写)
    	void a() 
    	{
    		cout << "Derived::a()" << endl;
    	}
    
    	// 多态
    	virtual void b()
    	{
    		cout << "Derived::b()" << endl;
    	}
    
    	// =========================================================================
    	//  子类和父类返回值参数不同,函数名相同,有/无virtual关键字 
    	// (注:函数重载与virtual关键字有无没有关系)
    	// =========================================================================
    
    	// 父类同名成员被隐藏
    	void d(int x, int y)
    	{
    		cout << "Derived::d() x = " << x << " y = " << y<< endl;
    	}
    
    	// 父类同名成员被隐藏
    	virtual void e(int x, int y)
    	{
    		cout << "Derived::e() x = " << x << " y = " << y << endl;
    	}
    
    	// =========================================================================
    	//  子类和父类返回值参数相同,函数名相同,函数返回值不同,有/无virtual关键字
    	// =========================================================================
    
    	// 返回值与基类不同
    	int f()
    	{
    		cout << "int Derived::f()" << endl;
    		return 1;
    	}
    
    	 错误
    	//virtual int g()
    	//{
    	//	cout << "virtual int Base::g()" << endl;
    	//	return 1;
    	//}
    };
    
    int main()
    {
    	// 用作参数
    	int xx = 100;
    
    	cout << "子类和父类返回值参数相同,函数名相同,无virtual关键字" << endl;
    	Derived d;
    	d.a();		
    	d.Base::a();	// 显示调用基类方法
    	cout << "子类和父类返回值参数相同,函数名相同,有virtual关键字" << endl;
    	Base* b = new Derived;
    	b->b();
    	cout << "子类和父类返回值参数不同,函数名相同,无virtual关键字" << endl;
    	d.d(xx, xx);
    	// d.d(xx); // 报错
    	d.Base::d(xx); // 显示调用
    	cout << "子类和父类返回值参数不同,函数名相同,有virtual关键字" << endl;
    	d.e(xx, xx);
    	//d.e(xx); // 报错
    	d.Base::e(xx);
    	cout << "子类和父类返回值参数相同,函数名相同,函数返回值不同, 无virtual关键字" << endl;
    	d.f();
    	d.Base::f();
    }



    展开全文
  • c++继承中重载、重写重定义的区别: 重载overload:是函数名相同,参数列表不同重载只是在类的内部存在。但是不能靠返回类型来判断。只在同一个类中。 重写override:也叫做覆盖。子类重新定义父类中有相同名称...

    原文链接:https://www.cnblogs.com/weizhixiang/articles/5760286.html
    c++继承中重载、重写、重定义的区别:
    重载overload:是函数名相同,参数列表不同重载只是在类的内部存在。但是不能靠返回类型来判断。只在同一个类中
    重写override:也叫做覆盖。子类重新定义父类中有相同名称和参数的虚函数。函数特征相同。但是具体实现不同,主要是在继承关系中出现的 。
    重写需要注意:

    1 被重写的函数不能是static的。必须是virtual的
    2 重写函数必须有相同的类型,名称和参数列表
    3 重写函数的访问修饰符可以不同。尽管virtual是private的,派生类中重写改写为public,protected也是可以的。

    重定义 (redefining)也叫做隐藏:

    子类重新定义父类中有相同名称的非虚函数 ( 参数列表可以不同 ) 。

    如果一个类,存在和父类相同的函数,那么,这个类将会覆盖其父类的方法,除非你在调用的时候,强制转换为父类类型,否则试图对子类和父类做类似重载的调用是不能成功的。
    class Base {
    private:
    virtual void display() { cout<<“Base display()”<<endl; }
    void say(){ cout<<“Base say()”<<endl; }
    public:
    void exec(){ display(); say(); }
    void f1(string a) { cout<<“Base f1(string)”<<endl; }
    void f1(int a) { cout<<“Base f1(int)”<<endl; } //overload,两个f1函数在Base类的内部被重载
    };

    class DeriveA:public Base{
    public:
    void display() { cout<<“DeriveA display()”<<endl; } //override,基类中display为虚函数,故此处为重写
    void f1(int a,int b) { cout<<“DeriveA f1(int,int)”<<endl; } //redefining,f1函数在Base类中不为虚函数,故此处为重定义
    void say() { cout<<“DeriveA say()”<<endl; } //redefining,同上
    };

    class DeriveB:public Base
    {
    public:
    void f1(int a) { cout<<“DeriveB f1(int)”<<endl; } //redefining,重定义
    };

    int main(){
    DeriveA a;
    Base *b=&a;
    b->exec(); //display():version of DeriveA call(polymorphism) //say():version of Base called(allways )

    b里边的函数display被A类覆盖,但是say还是自己的。

    a.exec(); //same result as last statement
    a.say();
    DeriveB c;
    c.f1(1); //version of DeriveB called
    }

    执行结果:
    在这里插入图片描述

    C++ 重写重载重定义区别

    综上所述,总结如下:
    1 成员函数重载特征:
    a 相同的范围(在同一个类中)
    b 函数名字相同
    c 参数不同
    d virtual关键字可有可无
    2 重写(覆盖)是指派生类函数覆盖基类函数,特征是:
    a 不同的范围,分别位于基类和派生类中
    b 函数的名字相同
    c 参数相同
    d 基类函数必须有virtual关键字
    3 重定义(隐藏)是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
    a 如果派生类的函数和基类的函数同名,但是参数不同,此时,不管有无virtual,基类的函数被隐藏。
    b 如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有vitual关键字,此时,基类的函数被隐藏。

    注意区分虚函数中的重载和重写:

    class A{
    public:
    virtual int fun(){}
    };


    class B:public A{
    int fun(int a){} //这是重载而不是重写:
    }


    int mian()
    {

    }


    class B:public A{
    int fun() // 从A继承来的 fun, 编译器会自己偷偷帮你加上
    int fun(int a){} // 新的fun, 和前面的只是名字一样的重载函数, 不是虚函数
    }

    展开全文
  • 重载overload 1.什么是重载 一个类中,函数名相同,函数形参类型或者数目不一样 ...子类重新定义父类中有相同名称参数虚函数。 重写需要注意: 1 被重写的函数不能是static。必须是virtual 2 ...

    重载overload

    1.什么是重载
    一个类中,函数名相同,函数的形参的类型或者数目不一样
    2.原理
    C++,底层函数的命名会将形参类型加上,所以底层不会把仅函数名相同的函数认为是同一个。
    所以C语言和C++混编要加“extend”

    重写override

    重写也叫覆盖
    子类重新定义父类中有相同名称和参数的虚函数。
    重写需要注意:
    1 被重写的函数不能是static的。必须是virtual的
    2 重写函数必须有相同的类型,名称和参数列表
    3 重写函数的访问修饰符可以不同。尽管virtual是private的,派生类中重写改写为public,protected也是可以的

    重定义 (redefining)

    也叫做隐藏
    子类重新定义父类中有相同名称的非虚函数 ( 参数列表可以不同 ) 。
    如果一个类,存在和父类相同的函数,那么,这个类将会覆盖其父类的方法,除非你在调用的时候,强制转换为父类类型,否则试图对子类和父类做类似重载的调用是不能成功的。

    如下:

    class base{
    public:
    	void foo(int a,int b){
    		cout<<"A";
    	}
    }; 
    class son:public base{
    public:
    	void foo(int a,double b){
    		cout<<"B";
    	}
    }; 
    int main(){
    	son s;
    	s.foo(1,1);				//这是foo是son的foo,输出B,重定义
    	s.foo(1,2.2);
    	s.base::foo(1,1);		//强制转换
    }
    
    展开全文
  • 重定义:若是在同一作用域内,定义了同名,参数类型个数也相同函数,编译时会出现重定义错误。但是若是派生类继承了父类,重新定义了该函数不会报错。而且,不管该函数参数类型是否一致,都会被派生类重定义。 ...
  • 创建于 2012-05-23 迁移自个人百度空间 -----------------------...子类重新定义父类中有相同名称参数虚函数。函数特征相同。但是具体实现不同,主要是在继承关系中出现 。 重写需要注意: 1 被重写的...
  • C++继承中重载、重写重定义的区别:重载overload:是函数名相同,参数列表不同 重载只是在类的内部存在。但是不能靠返回类型来判断。重写override:也叫做覆盖。子类重新定义父类中有相同名称参数的虚函数。...
  • 重载属于静态多态,而不是通过继承虚函数实现动态多态。编译器会根据这些函数参数列表不同,将同名函数名称做修饰,从而生成不同名称预处理函数。 eg: double max(double x,double y), int max(int x,...
  • 子类重新定义父类中有相同名称参数虚函数。函数特征相同。但是具体实现不同,主要是在继承关系中实现重写需要注意: (1)被重写的函数不能是static且必须是virtual。 (2)重写函数必须有相同类型,名称...
  • 重写、重载和重定义的区别

    千次阅读 2015-03-13 22:21:44
    简单分析了重写(override),重载,重定义的区别
  • 1 成员函数重载特征: a 相同范围(在同一个类中) b 函数名字相同 c 参数不同 d virtual关键字可有可无2 ...c 参数相同 d 基类函数必须有virtual关键字3 重定义(隐藏)是指派生类函数屏蔽了与其同名基类函数,...
  • 子类重新定义父类中有相同名称参数虚函数。函数特征相同。但是具体实现不同,主要是在继承关系中出现 。 重写需要注意: 1 被重写的函数不能是static。必须是virtual重写函数必须有相同类型,...
  • C++ 重写重载重定义区别  重载overload:是函数名相同,参数列表不同 重载只是在类内部存在。但是不能靠返回类型来判断。 重写override:也叫做覆盖。子类重新定义父类中有相同名称参数...
  • 重载overload:是函数名相同,参数列表不同 重载只是在类内部存在。但是不能靠返回类型来判断。 重写override:也叫做覆盖。子类重新定义父类中有相同名称参数虚函数。函数特征相同。...重定义
  • 重写:父类与子类之间多态性。子类重新定义父类中由相同名称参数虚函数;被重写的函数不能时static,必须是virtual重写函数必须由相同类型,名称参数列表;...重定义:子类重新定...
  • 1 成员函数重载特征: a 相同范围(在同一个类中) ...3 重定义(隐藏)是指派生类函数屏蔽了与其同名基类函数,规则如下: a 如果派生类函数基类函数同名,但是参数不同,此时,不管有无virtu...
  • 重定义:也叫做隐藏,子类重新定义父类中有相同名称非虚函数( 参数列表可以不同 ) ,指派生类函数屏蔽了与其同名基类函数。可以理解成发生在继承中重载。 重写:也叫做覆盖,一般发生在子类父类继承关系...

空空如也

空空如也

1 2 3 4 5 ... 18
收藏数 352
精华内容 140
关键字:

重写和重定义的区别