wic*_*ich 98
抽象类是一个声明了一个或多个方法但未定义的类,这意味着编译器知道这些方法是类的一部分,而不是该方法要执行的代码.这些被称为抽象方法.这是一个抽象类的示例.
class shape {
public:
virtual void draw() = 0;
};
Run Code Online (Sandbox Code Playgroud)
这声明了一个抽象类,它指定类的任何后代应该实现draw方法(如果该类是具体的).您无法实例化此类,因为它是抽象的,毕竟,如果您调用成员绘制,编译器将不知道要执行的代码.所以你不能做到以下几点:
shape my_shape();
my_shape.draw();
Run Code Online (Sandbox Code Playgroud)
为了能够实际使用draw方法,您需要从这个抽象类派生类,它实现了draw方法,使类具体化:
class circle : public shape {
public:
circle(int x, int y, int radius) {
/* set up the circle */
}
virtual draw() {
/* do stuff to draw the circle */
}
};
class rectangle : public shape {
public:
rectangle(int min_x, int min_y, int max_x, int max_y) {
/* set up rectangle */
}
virtual draw() {
/* do stuff to draw the rectangle */
}
};
Run Code Online (Sandbox Code Playgroud)
现在,您可以实例化具体对象circle和rectangle并使用它们的draw方法:
circle my_circle(40, 30, 10);
rectangle my_rectangle(20, 10, 50, 15);
my_circle.draw();
my_rectangle.draw();
Run Code Online (Sandbox Code Playgroud)
当然问题是,你为什么要这样做?难道你不能定义圆形和矩形类并且已经废除了整个形状类吗?你可以,但是你将无法利用他们的继承:
std::vector<shape*> my_scene;
my_scene.push_back(new circle(40, 30, 10));
my_scene.push_back(new rectangle(20, 10, 50, 15));
std::for_each(my_scene.begin(), my_scene.end(), std::mem_fun_ref(&shape::draw)
Run Code Online (Sandbox Code Playgroud)
这段代码让你将所有形状收集到一个容器中.如果你的场景中有很多形状和许多不同的形状,这将使它变得容易多了.例如,我们现在可以一次性绘制所有形状,而这样做的代码甚至不需要知道我们拥有的不同类型的形状.
最后我们需要知道为什么shape的draw函数是抽象的,而不仅仅是一个空函数,即为什么我们不定义:
class shape {
public:
virtual void draw() {
/* do nothing */
}
};
Run Code Online (Sandbox Code Playgroud)
这样做的原因是我们并不真正想要类型为对象的对象,无论如何它们都不是真实的东西,它们是抽象的.因此,为draw方法定义一个实现没有任何意义,即使是空方法.使shape类抽象可以防止我们错误地实例化shape类,或者错误地调用基类的空draw函数而不是派生类的draw函数.实际上,我们为任何想要表现形状的类定义一个接口,我们说任何这样的类都应该有一个看起来像我们已经指定它的draw方法.
为了回答你的最后一个问题,没有任何"普通派生类"这样的东西,每个类都是抽象的或具体的.具有任何抽象方法的类是抽象的,任何不具体的类都是具体的.它只是区分两类类的一种方法.基类可以是抽象的也可以是具体的,派生类可以是抽象的也可以是具体的:
class abstract_base {
public:
virtual void abstract_method1() = 0;
virtual void abstract_method2() = 0;
};
class concrete_base {
public:
void concrete_method1() {
/* do something */
}
};
class abstract_derived1 : public abstract_base {
public:
virtual void abstract_method3() = 0;
};
class abstract_derived2 : public concrete_base {
public:
virtual void abstract_method3() = 0;
};
class abstract_derived3 : public abstract_base {
public:
virtual abstract_method1() {
/* do something */
}
/* note that we do not provide an implementation for
abstract_method2 so the class is still abstract */
};
class concrete_derived1 : public concrete_base {
public:
void concrete_method2() {
/* do something */
}
};
class concrete_derived2 : public abstract_base {
public:
virtual void abstract_method1() {
/* do something */
}
virtual void abstract_method2() {
/* do something */
}
/* This class is now concrete because no abstract methods remain */
};
Run Code Online (Sandbox Code Playgroud)
小智 23
抽象类不能用于创建对象.而具体类可用于创建对象.
具体意味着" 在现实中或在实际经验中存在; 被感官察觉; 真实''.然而,抽象意味着" 不适用或不实际; 理论上的.
一个抽象类不能被实例化.然而,具体的可以.
一个抽象类是具有一个或多个纯虚函数.而具体类没有纯虚函数.
Jan*_*ice 20
具体类是可用于创建对象的类.抽象类不能用于创建对象(必须扩展抽象类并使具体类能够创建对象).
假装有一台机器可以"盖章"原材料并制造汽车.压模是一个具体的类.由此我们可以创建汽车对象.抽象类将是压模的蓝图.你不能用压模的蓝图制造汽车,你需要先从蓝图上制作压模类.
归档时间: |
|
查看次数: |
93052 次 |
最近记录: |