- 运行了一段书上的代码,发现不一样
使用的是vs2019
#include<iostream>
using namespace std;
class Base {
public:
virtual void fun1() { cout << "Base::fun1()" << endl; }
virtual ~Base() {}
};
class Derived1: public Base {
public:
virtual void fun1() { cout << "Derived1::fun1()" << endl; }
virtual void fun2() { cout << "Derived1::fun2()" << endl; }
};
class Derived2 : public Base {
public:
virtual void fun1() { cout << "Derived2::fun1()" << endl; }
virtual void fun2() { cout << "Derived2::fun2()" << endl; }
};
void fun(Base* b) {
b->fun1();
Derived1* d = dynamic_cast<Derived1*>(b);
if (d != 0) d->fun2();
}
int main(){
Base b;
fun(&b);
Derived1 d1;
fun(&d1);
Derived2 d2;
fun(&d2);
return 0;
}
运行结果
Base::fun1()
Derived1::fun1()
Derived1::fun2()
Derived2::fun1()
郑莉 董渊 何江舟编著的《C++语言程序设计(第四版)》338页说还有一行Derived2::fun2(),解释是 “d2是Derived2类型的对象,由于Derived2是Derived1的派生类,对指向d2的指针执行转换,也能够成功得到Derived1类型的指针”
但是运行结果却没有,因为类型不符合,返回的是nullptr。
- 虚函数小实验
#include<iostream>
#include<typeinfo>
using namespace std;
class Base {
public:
virtual ~Base() {}
virtual void f1() {
cout << "Base::f1" << endl;
}
};
class Derived :public Base {
public:
virtual void f1() {
cout << "Derived::f1" << endl;
}
};
int main(){
Base b;
b.f1();
Derived d;
d.f1();
return 0;
}
结果:
Base::f1
Derived::f1
- 编写一个计数器Counter类,对其重载运算符“+”
#include<iostream>
using namespace std;
class Counter {
public:
Counter(int a) { i = a; }
Counter operator+( Counter b) const {
return Counter(i + b.i);
}
void get() { cout << i << endl; }
private:
int i;
};
int main(){
Counter a(3),b(5),c(0);
c = a + b;
c.get();
return 0;
}
- 对类Point重载“++”(自增),“–”(自减)运算符,要求同时重载前缀和后缀的形式。
#include<iostream>
using namespace std;
class Point {
public:
Point(int a) { i = a; }
Point operator+( Point b) const {//双目运算符
return Point(i + b.i);
}
Point& operator++();//前置运算符
Point operator++(int);//后置运算符
void get() { cout << i << endl; }
private:
int i;
};
//前置运算符
Point &Point::operator++() {
i++;
return *this;
}
//后置运算符
Point Point::operator++(int) {
Point old = *this;
i++;
return old;
}
int main(){
Point a(3),b(5),c(0);
c = a + b;
c.get();
++c;
c.get();
c++;
c.get();
c++.get();
return 0;
}//“--”略
- 编写抽象类Shape,由此派生出Rectangle和Circle,二者都有计算对象面积的函数getArea()、计算对象周长的函数getPerim()。
#include<iostream>
using namespace std;
class Shape {
public:
virtual ~Shape() {}
virtual double getArea() = 0;
virtual double getPerim() = 0;
};
class Rectangle :public Shape {
public:
Rectangle(double w, double h) { width = w; height = h; }
virtual double getArea() {
return width * height;
}
virtual double getPerim() {
return 2*(width + height);
}
private:
double width;
double height;
};
class Circle :public Shape {
public:
Circle(double r) { radius = r; }
virtual double getArea() {
return 3.1415 * radius * radius;
}
virtual double getPerim() {
return 2 * 3.1415 * radius;
}
private:
double radius;
};
int main(){
Rectangle r(3, 4);
cout << "Area of r : "<<r.getArea() << endl;
cout << "Perim of r : " << r.getPerim() << endl;
Circle c(5);
cout << "Area of c : " << c.getArea() << endl;
cout << "Perim of c : " << c.getPerim() << endl;
return 0;
}
- 在上题基础上,通过继承Rectangle得到一个新的类Square,然后在Shape中增加一个函数getVertaxCount()const用来获得当前图形的顶点个数。用以下几种方法分别实现,并体会各自优劣。
(1)使用dynamic_cast实现Shape::getVertexCount函数
(2)使用typeid实现Shape::getVertexCount函数
(3)将Shape::getVertexCount声明为纯虚函数,在派生类中给出具体实现。
#include<iostream>
using namespace std;
class Shape {
public:
virtual ~Shape() {}
virtual double getArea() = 0;
virtual double getPerim() = 0;
int getVertexCount1();//(1)使用dynamic_cast实现
int getVertexCount2();//(2)使用typeid实现
virtual int getVertexCount() = 0;//(3)纯虚函数,在派生类中实现
};
class Rectangle :public Shape {
public:
Rectangle(double w, double h) { width = w; height = h; }
virtual double getArea() {
return width * height;
}
virtual double getPerim() {
return 2*(width + height);
}
virtual int getVertexCount() {
return 4;
}
private:
double width;
double height;
};
class Square :public Rectangle {
public:
Square(double w) :Rectangle(w, w) {}
virtual int getVertexCount() {
return 4;
}
};
class Circle :public Shape {
public:
Circle(double r) { radius = r; }
virtual double getArea() {
return 3.1415 * radius * radius;
}
virtual double getPerim() {
return 2 * 3.1415 * radius;
}
virtual int getVertexCount() {
return 0;
}
private:
double radius;
};
//(1)使用dynamic_cast实现
int Shape::getVertexCount1() {
Rectangle* r = dynamic_cast<Rectangle*>(this);
if (r != NULL)return 4;
Circle *c = dynamic_cast<Circle*>(this);
if (c != NULL)return 0;
return -1;
}
int Shape::getVertexCount2() {
const type_info &r = typeid(*this);
if (r == typeid(Rectangle))return 4;
else if (r == typeid(Square))return 4;
else if (r == typeid(Circle))return 0;
else return -1;
}
int main(){
Rectangle r(3, 4);
cout << "1.Rectangle:" << r.getVertexCount1() << endl;
cout << "2.Rectangle:" << r.getVertexCount2() << endl;
cout << "3.Rectangle:" << r.getVertexCount() << endl;
Square s(6);
cout << "1.Square:" << s.getVertexCount1() << endl;
cout << "2.Square:" << s.getVertexCount2() << endl;
cout << "3.Square:" << s.getVertexCount() << endl;
Circle c(5);
cout << "1.Circle:" << c.getVertexCount1() << endl;
cout << "2.Circle:" << c.getVertexCount2() << endl;
cout << "3.Circle:" << c.getVertexCount() << endl;
return 0;
}