我现在在一个班学习C ++,我不太神交纯虚函数。 据我所知,他们后来在派生类中列出,但你为什么要其声明为等于0,如果你只是在派生类中定义的?
Answer 1:
简单地说,它是使抽象类,所以它不能被实例化,但子类可以覆盖纯虚方法,形成一个具体的类。 这是定义在C ++的界面的好方法。
Answer 2:
这迫使派生类中定义的功能。
Answer 3:
任何含纯虚拟方法类将是抽象的,也就是说,它不能被实例化。 抽象类定义子类应该分享一些核心的行为,但允许(事实上,要求)子类分别实现抽象有用。
一个抽象类的例子:
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;
};
Answer 4:
在C ++中的纯虚拟方法基本上一种方式来定义接口 ,而不需要他们来实现。
Answer 5:
想象一下,我想了几种形状的模型,都有一个明确的区域。 我决定每一个形状必须继承IShape
(“我”的接口)和IShape
将包括GetArea()
方法:
class IShape {
virtual int GetArea();
};
现在的问题:我应该怎么计算形状的面积如果形状不重写GetArea()
也就是说,什么是最好的默认实现? 圆圈使用PI *半径^ 2,正方形使用长度^ 2,平行四边形和长方形使用基*高,三角形使用1/2基*高,菱形,五边形,八边形等使用其他公式。
所以我说“如果你的形状,你必须定义一个方法来计算面积,但该死的,如果我知道会是什么”的定义方法纯虚:
class IShape {
virtual int GetArea() = 0;
};
Answer 6:
要添加到史蒂芬Sudit的回答:
“简单地说,它是使抽象类,所以它不能被实例化,但子类可以覆盖纯虚方法,形成一个具体的类,这是定义在C ++接口的好办法。”
这方面的一个例子是,如果你有一个基类(也许形状),你用它来定义一些,它的派生类可以使用成员函数,但要防止形状的实例正在申报并强制用户仅使用派生类(其可以是,矩形,三角形,五边形等)
RE:杰夫的上面的回答
非抽象类可以包含虚拟成员函数和被实例化。 事实上,对于重载成员函数这是必需的,通过默认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();
没有虚拟关键字,只有年龄会被打印出来,而不是年龄和studentID为是应该发生的学生类
(本实施例中是基于从C非常相似的一个++ Java程序员http://www.amazon.com/Java-Programmers-Mark-Allen-Weiss/dp/013919424X )
@Steven Sudit:你是完全正确的,我忘了把实际的继承,卫生署! 访问器等不包括让事情变得更清晰,我做了,现在越来越明显。 09年3月7日:所有的固定
Answer 7:
从本质上讲,纯虚被用来创建(类似于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;
}
学校并不需要知道如何设置一个学生的名字,它需要知道一切是如何得到学生的姓名。 通过提供学生一个接口来实现,并使用学校,有什么是需要学校的功能来执行其工作的两片之间的协议。 现在,(因为我们每次都实现相同的接口,只要)我们可以切换进出学生类的所有我们想要的不同实现在不影响学校。
Answer 8:
抽象类的想法是,你仍然可以有与该类型(即,它是静态类型)声明的变量,但变量实际上指或指向一个实际的具体类型(动态类型)。
当你调用C ++中的方法,编译器需要确保该方法将在该对象上的支持。
通过声明的纯虚函数,你是把一个“占位符”,编译器可以用来说:“哦......我知道,无论最终由这个变量被称为将接受呼叫”,因为实际的具体类型将实施它。 但是,您不必提供抽象类型的实现。
如果没有声明什么,那么编译器将有保证,它将所有亚型来实现的没有有效的方法。
当然,如果你问你为什么会想使一个抽象类,有很多围绕信息上的。