C++ 教程 在线

1934C++ 重载运算符和重载函数

类重载、覆盖、重定义之间的区别:

重载指的是函数具有的不同的参数列表,而函数名相同的函数。重载要求参数列表必须不同,比如参数的类型不同、参数的个数不同、参数的顺序不同。如果仅仅是函数的返回值不同是没办法重载的,因为重载要求参数列表必须不同。(发生在同一个类里)

 覆盖是存在类中,子类重写从基类继承过来的函数。被重写的函数不能是static的。必须是virtual的。但是函数名、返回值、参数列表都必须和基类相同(发生在基类和子类)

 重定义也叫做隐藏,子类重新定义父类中有相同名称的非虚函数 ( 参数列表可以不同 ) 。(发生在基类和子类)

1933C++ 重载运算符和重载函数

值得注意的是:
  • 1、运算重载符不可以改变语法结构。
  • 2、运算重载符不可以改变操作数的个数。
  • 3、运算重载符不可以改变优先级。
  • 4、运算重载符不可以改变结合性。

1932C++ 继承

另外多继承(环状继承),A->D, B->D, C->(A,B),例如:

class D{......};
class B: public D{......};
class A: public D{......};
class C: public B, public A{.....};

这个继承会使D创建两个对象,要解决上面问题就要用虚拟继承格式

格式:class 类名: virtual 继承方式 父类名

class D{......};
class B: virtual public D{......};
class A: virtual public D{......};
class C: public B, public A{.....};

虚继承--(在创建对象的时候会创建一个虚表)在创建父类对象的时候

A:virtual public D
B:virtual public D

实例:

#include <iostream>

using namespace std;
//基类

class D
{
public:
    D(){cout<<"D()"<<endl;}
    ~D(){cout<<"~D()"<<endl;}
protected:
    int d;
};

class B:virtual public D
{
public:
    B(){cout<<"B()"<<endl;}
    ~B(){cout<<"~B()"<<endl;}
protected:
    int b;
};

class A:virtual public D
{
public:
    A(){cout<<"A()"<<endl;}
    ~A(){cout<<"~A()"<<endl;}
protected:
    int a;
};

class C:public B, public A
{
public:
    C(){cout<<"C()"<<endl;}
    ~C(){cout<<"~C()"<<endl;}
protected:
    int c;
};

int main()
{
    cout << "Hello World!" << endl;
    C c;   //D, B, A ,C
    cout<<sizeof(c)<<endl;
    return 0;
}

1931C++ 面向对象 C++ 类 & 对象

1930C++ 面向对象 C++ 类 & 对象

在类的外面,其实也可以用指针访问类内部的私有成员,例如:

#include <iostream>
using namespace std;

class a    // 定义了类a
{
    long a0;   // 定义私有成员 a0
    public:
    a(long b)
    {
        a0=b;
    }
    void geta()
    {
        cout<<a0<<endl;
    }
};
int main()
{
    a b(5);          // 定义对象b,并给 b 中的 a0 赋初值
    long *p;
    p=(long*)&b;     // 令指针 p 指向 b 中前 4 个字节,在这里相当于指向 a0
    b.geta();        // 用内部函数访问 a0
    cout<<*p<<endl;  // 在外部直接访问 a0
    *p=8;            // 在外部改变 a0 的值
    b.geta();        // 输出改变后的结果
    cout<<*p<<endl;
    return 0;
}

需要注意的是,使用这种方法虽然可以用于基于类的多态原则的一些程序开发,但违反了类的封装原则,在使用指针的类中也极不安全,所以不建议使用。