纯虚函数在C ++中的用途是什么?

时间:2009-07-01 20:07:21

标签: c++ virtual-functions pure-virtual

我现在正在课堂上学习C ++,而且我不太熟悉纯虚函数。我知道它们稍后在派生类中概述,但是如果你要在派生类中定义它,为什么要将它声明为等于0?

8 个答案:

答案 0 :(得分:32)

简单地说,它是使类抽象化,以便它不能被实例化,但子类可以覆盖纯虚方法以形成具体类。这是在C ++中定义接口的好方法。

答案 1 :(得分:12)

这会强制派生类定义函数。

答案 2 :(得分:7)

任何包含纯虚方法的类都是抽象的,也就是说,它不能被实例化。抽象类对于定义子类应该共享的一些核心行为很有用,但允许(实际上需要)子类单独实现抽象。

抽象类的一个例子:

class Foo {

    // pure virtual, must be implemented by subclasses
    virtual public void myMethod() = 0;

    // normal method, will be available to all subclasses,
    // but *can* be overridden
    virtual public void myOtherMethod();
};

每个方法都是抽象的类可以用作接口,要求所有子类通过实现其中包含的所有方法来符合接口。

界面的一个例子:

class Bar {

    // all method are pure virtual; subclasses must implement
    // all of them
    virtual public void myMethod() = 0;

    virtual public void myOtherMethod() = 0;
};

答案 3 :(得分:4)

C ++中的纯虚方法基本上是一种定义接口的方法,而不需要实现它们。

答案 4 :(得分:3)

添加到Steven Sudit的回答:

“简而言之,它是使类抽象,因此无法实例化,但子类可以覆盖纯虚方法以形成具体类。这是在C ++中定义接口的好方法。 “

如果您有一个基类(可能是Shape),您可以使用它来定义其派生类可以使用的多个成员函数,但希望阻止声明Shape实例并强制用户使用仅使用派生类(可以是Rectangle,Triangle,Pentagon等)

RE:Jeff的回答

非抽象类可以包含虚拟成员函数并进行实例化。实际上,对于重载成员函数,这是必需的,因为默认情况下C ++不确定变量的运行时类型,但是当使用虚拟关键字定义时,它将会。

考虑这段代码(为了清楚起见,不包括注释,访问器,变换器,构造器等):

class Person{
  int age;

  public:
    virtual void print(){
      cout << age <<endl;
    }
}

class Student: public Person{
  int studentID

  public:
    void print(){
      cout << age << studentID <<endl;
    }
}

现在运行此代码时:

 Person p = new Student();
 p.print();

没有虚拟关键字,只打印年龄,而不是学生班应该发生的年龄和学生ID

(这个例子基于c ++中非常类似的java程序员http://www.amazon.com/Java-Programmers-Mark-Allen-Weiss/dp/013919424X

@Steven Sudit:你是完全正确的,我忽略了包括实际的继承,doh!不包括访问器等以使事情更清楚,我现在已经更明显了。 3-7-09:全部固定

答案 5 :(得分:3)

想象一下,我想要模拟几种形状,并且都有一个明确定义的区域。我决定每个形状都必须继承IShape(接口为“I”),IShape将包含GetArea()方法:

class IShape {
    virtual int GetArea();
};

现在问题是:如果该形状没有覆盖GetArea(),我该如何计算形状的面积?也就是说,什么是最好的默认实现?圆圈使用pi * radius ^ 2,正方形使用长度^ 2,平行四边形和矩形使用base * height,三角形使用1/2 base * height,菱形,五边形,八边形等。使用其他公式。

所以我说“如果你是一个形状,你必须定义一种计算面积的方法,但是如果我知道那将是什么”该死的方法是通过定义纯虚拟方法:

class IShape {
    virtual int GetArea() = 0;
};

答案 6 :(得分:1)

基本上,纯虚拟用于创建接口(类似于java)。这可以用作两个模块(或类或其他)之间关于期望什么样的功能的协议,而不必知道关于另一个部分的实现的任何信息。这使您可以使用相同的界面轻松即插即用,而无需更改使用您的界面的其他模块中的任何内容。

例如:

class IStudent
{
    public:
    virtual ~IStudent(){};
    virtual std::string getName() = 0;
};


class Student : public IStudent
{
    public:
    std::string name;
    std::string getName() { return name; };
    void setName(std::string in) { name = in; };
};

class School
{
    public:
    void sendStudentToDetention(IStudent *in) {
        cout << "The student sent to detention is: ";
        cout << in->getName() << endl;
    };
};

int main()
{
    Student student;
    student.setName("Dave");

    School school;
    school.sendStudentToDetention(&student);
return 0;
}

学校不需要知道如何设置学生的姓名,所有需要知道的是如何获得学生的姓名。通过为学生提供实施和学校使用的界面,两者之间就学校执行其工作所需的功能达成了协议。现在我们可以在不影响学校的情况下切换进出Student类的不同实现(只要我们每次都实现相同的接口)。

答案 7 :(得分:0)

抽象类的想法是你仍然可以使用该类型声明一个变量(即,它是静态类型),但变量实际上引用或指向实际的具体类型(动态类型)。 p>

在C ++中调用方法时,编译器需要确保该对象支持该方法。

通过声明纯虚函数,您将放置一个“占位符”,编译器可以使用它来说“哦......我知道这个变量最后引用的内容将接受该调用”因为实际具体类型将实现它。但是,您不必以抽象类型提供实现。

如果您没有声明任何内容,那么编译器将没有有效的方法来保证它将由所有子类型实现。

当然,如果你问为什么要把课程抽象化,那么就会有很多信息。