C++中的接口(纯虚函数)

在C++中,接口通常用纯虚函数的形式来实现。纯虚函数是一种没有实现的虚函数,其定义需要在派生类中完成。接口中只有纯虚函数,没有数据成员和函数定义,因此派生类必须实现接口中定义的所有纯虚函数,否则编译器会报错。

接口可以用于实现多态性,一个类可以继承多个接口,从而具有多个行为。例如,一个图形界面程序可以定义一个绘制图形的接口和一个处理用户输入的接口,不同的图形对象可以继承不同的接口,以实现不同的行为。

以下是一个简单的接口示例:

class Shape {
public:
    virtual void draw() = 0;
};

class Circle : public Shape {
public:
    void draw() {
        // 绘制圆形
    }
};

class Square : public Shape {
public:
    void draw() {
        // 绘制正方形
    }
};

在这个示例中,Shape类是一个接口,定义了一个纯虚函数draw()。Circle和Square类都继承了Shape类,并实现了draw()函数来绘制不同的形状。

接口的使用可以使代码更加模块化和可扩展,同时也可以提高代码的可读性和可维护性。但是,过多的接口也可能会使代码过于复杂,因此在设计时需要权衡利弊,尽量避免过多的接口设计。

其实C++没有interface 关键字

在C++中,接口的实现通常采用纯虚函数的形式。纯虚函数是没有实现的虚函数,其定义需要在派生类中完成。接口中没有数据成员和函数定义,只有纯虚函数,因此派生类必须实现接口中定义的所有纯虚函数。接口可以实现多态性,一个类可以继承多个接口,以具有不同的行为。在设计时需要权衡利弊,尽量避免过多的接口设计。

下面是一个关于接口多态的例子:

// Shape.h
class Shape {
public:
    virtual void draw() = 0;
};

// Colorful.h
class Colorful {
public:
    virtual void setColor(int r, int g, int b) = 0;
};

// Circle.h
class Circle : public Shape, public Colorful {
public:
    void draw() override {
        // 绘制圆形
    }
    void setColor override (int r, int g, int b) {
        // 设置圆形的颜色
    }
};

// Square.h
class Square : public Shape, public Colorful {
public:
    void draw() override {
        // 绘制正方形
    }
    void setColor override ****(int r, int g, int b) {
        // 设置正方形的颜色
    }
};

// main.cpp
int main() {
    Shape* shapes[2];
    shapes[0] = new Circle();
    shapes[1] = new Square();
    for (int i = 0; i < 2; i++) {
        shapes[i]->draw();
        Colorful* colorful = dynamic_cast<Colorful*>(shapes[i]);
        if (colorful != nullptr) {
            colorful->setColor(255, 0, 0);
        }
    }
    return 0;
}

在这个例子中,Shape类和Colorful类都是接口,Circle和Square类都继承了Shape类和Colorful类,并实现了draw()函数和setColor()函数来绘制不同的形状和设置不同的颜色。在main函数中,创建了一个Shape指针数组shapes,其中存放了一个Circle对象和一个Square对象。通过循环依次调用它们的draw()函数,并通过dynamic_cast将它们转换成Colorful指针,最后通过setColor()函数设置它们的颜色。

这个例子展示了接口的多态特性,通过继承不同的接口,一个类可以具有多个行为,可以在不同的情况下调用不同的函数实现不同的功能。

多态:接收一个接口作为参数

在C++中,多态可以通过接收一个接口作为参数来实现。例如,一个函数可以接收一个Shape接口作为参数,从而可以接收任意实现了Shape接口的类的对象。这样,函数就可以在不知道具体对象类型的情况下调用对象的函数

以下是一个简单的例子:

void drawShape(Shape* shape) {
    shape->draw();
}

int main() {
    Circle circle;
    Square square;
    drawShape(&circle);
    drawShape(&square);
    return 0;
}

在这个例子中,drawShape()函数接收一个Shape接口作为参数,并调用它的draw()函数来绘制图形。在main函数中,创建了一个Circle对象和一个Square对象,并将它们的地址传递给drawShape()函数。由于Circle和Square都继承了Shape接口并实现了它的draw()函数,因此可以成功地调用它们的draw()函数来绘制图形。

多态可以使代码更加灵活和可扩展,同时也可以提高代码的可读性和可维护性。但是,过多的多态也可能会使代码过于复杂,因此在设计时需要权衡利弊,尽量避免过多的多态设计。

Xuanwei Zhang
Xuanwei Zhang
Software Engineer

My research interests include distributed database, distributed storage system and internet of things