0

仮想関数を理解しようとしています。put() 関数を仮想化するにはどうすればよいですか? コードに必要な変更は何ですか?

#include <iostream>
#include <string>
using namespace std;

class Circle
{
public:
    Circle(double radius) {this->radius = radius; }
    void put() const {cout << "Radius = " << radius;}
private:
    double radius;
};

class ColoredCircle: public Circle
{
public:
    ColoredCircle(double radius, string color);
    void put() const;
private:
    string color;
};

ColoredCircle::ColoredCircle(double radius, string color)
    : Circle(radius), color(color) {}

void ColoredCircle::put() const
{
    Circle::put();
    cout << " Color = " << color;
}

int main()
{
    ColoredCircle redCircle(100., "red");
    Circle* circle1 = &redCircle;
    circle1->put();
    cout << endl;
    Circle circle(50.);
    Circle* circle2 = &circle;
    circle2->put();
    cout << endl;
    std::cin.get();
    return 0;
}
4

1 に答える 1

1

virtual基本クラスの関数の前にキーワードを記述するだけです。

class Circle
{
public:
    Circle(double radius) {this->radius = radius; }
    virtual void put() const {cout << "Radius = " << radius;}
//  ^^^^^^^
private:
    double radius;
};

virtualただし、関数が使用されるケースを理解する必要があります。出演料はいくらなのか、なぜ役に立つのかなど...

ちょっとした答え: Aは、同じシグネチャの継承内で動作をオーバーライドできるvirtual method特別なものです。methodclassmethod

パフォーマンス コストについて :仮想関数を呼び出すと、測定可能なオーバーヘッドが確実に発生します。呼び出しでは、vtableを使用して、そのタイプのオブジェクトの関数のアドレスを解決する必要があります。余分な指示はあなたの心配の最小です. vtable は多くの潜在的なコンパイラの最適化を妨げるだけでなく、I-Cache をスラッシングする可能性もあります。

もちろん、これらのペナルティが重要かどうかは、アプリケーション、それらのコード パスが実行される頻度、および継承パターンによって異なります。

仮想関数に関するいくつかの記事を読むことをお勧めします。ここに完全なリストはありません:

于 2013-07-13T17:38:53.780 に答える