好,不要看答案,请你写出以下程序完整的输出(包括哪些语法有问题):
#include <iostream>
class Base {
public:
Base() {
std::cout << "Base::construct\n";
}
virtual ~Base() {
std::cout << "Base::destruct\n";
}
virtual void foo() {
std::cout << "Base::foo()\n";
}
void fun() {
std::cout << "Base::fun()\n";
}
void bar() {
std::cout << "Base::bar()\n";
}
};
class Derive : public Base {
public:
Derive() {
std::cout << "Derive::construct\n";
}
~Derive() {
std::cout << "Derive::destruct\n";
}
void foo() override {
std::cout << "Derive::foo()\n";
}
void fun() {
std::cout << "Derive::fun()\n";
}
virtual void bar() {
std::cout << "Derive::bar()\n";
}
};
void fun1(Base *base) {
std::cout << "void fun1(Base * base)\n";
}
void fun2(Derive *derive) {
std::cout << "void fun2(Derive * derive)\n";
}
int main() {
// 测试一:基类指针指向基类成员
{
Base b1;
Base *b2 = &b1;
b1.foo();
b1.fun();
b1.bar();
b2->foo();
b2->fun();
b2->bar();
fun1(&b1);
fun1(b2);
fun2(&b1);
fun2(b2);
}
std::cout << "\n\n----------------------------\n\n";
// 测试二:基类指针指向子类成员
{
Derive d;
Base *b = &d;
d.foo();
d.fun();
d.bar();
b->foo();
b->fun();
b->bar();
fun1(&d);
fun1(b);
fun2(&d);
fun2(b);
}
std::cout << "\n\n----------------------------\n\n";
// 测试三:子类指针指向基类成员
{
Base b;
Derive *d = &b;
b.foo();
b.fun();
b.bar();
d->foo();
d->fun();
d->bar();
fun1(&b);
fun1(d);
fun2(&b);
fun2(d);
}
std::cout << "\n\n----------------------------\n\n";
// 测试四:子类指针指向子类
{
Derive d1;
Derive *d2 = &d1;
d1.foo();
d1.fun();
d1.bar();
d2->foo();
d2->fun();
d2->bar();
fun1(&d1);
fun1(d2);
fun2(&d1);
fun2(d2);
}
return 0;
}
如果你不是信手拈来,那这篇博客对你有价值,请先看答案,给自己打打分数:
Base::construct
Base::foo()
Base::fun()
Base::bar()
Base::foo()
Base::fun()
Base::bar()
void fun1(Base * base)
void fun1(Base * base)
void fun2(Derive * derive)
void fun2(Derive * derive)
Base::destruct
----------------------------
Base::construct
Derive::construct
Derive::foo()
Derive::fun()
Derive::bar()
Derive::foo()
Base::fun()
Base::bar()
void fun1(Base * base)
void fun1(Base * base)
void fun2(Derive * derive)
void fun2(Derive * derive)
Derive::destruct
Base::destruct
----------------------------
Base::construct
Base::foo()
Base::fun()
Base::bar()
Base::foo()
Derive::fun()
void fun1(Base * base)
void fun1(Base * base)
void fun2(Derive * derive)
void fun2(Derive * derive)
Base::destruct
----------------------------
Base::construct
Derive::construct
Derive::foo()
Derive::fun()
Derive::bar()
Derive::foo()
Derive::fun()
Derive::bar()
void fun1(Base * base)
void fun1(Base * base)
void fun2(Derive * derive)
void fun2(Derive * derive)
Derive::destruct
Base::destruct
怎么样,是不是感觉到自己还存在一些问题,请看具体代码注释:
#include <iostream>
// 基类
class Base {
public:
Base() {
std::cout << "Base::construct\n";
}
// 虚析构
virtual ~Base() {
std::cout << "Base::destruct\n";
}
// virtual,产生多态的关键字
virtual void foo() {
std::cout << "Base::foo()\n";
}
// 普通成员函数
void fun() {
std::cout << "Base::fun()\n";
}
// 普通成员函数
void bar() {
std::cout << "Base::bar()\n";
}
};
// 子类
class Derive : public Base {
public:
Derive() {
std::cout << "Derive::construct\n";
}
~Derive() {
std::cout << "Derive::destruct\n";
}
// 重写,override
void foo() override {
std::cout << "Derive::foo()\n";
}
// 普通成员函数
void fun() {
std::cout << "Derive::fun()\n";
}
// 加上关键字 virtual 的普通成员函数
virtual void bar() {
std::cout << "Derive::bar()\n";
}
};
// 基类指针作参数
void fun1(Base *base) {
std::cout << "void fun1(Base * base)\n";
}
// 子类指针作参数
void fun2(Derive *derive) {
std::cout << "void fun2(Derive * derive)\n";
}
int main() {
// 测试一:基类指针指向基类成员
{
Base b1; // 新建基类对象,调用构造函数,输出 Base::construct
Base *b2 = &b1; // 指向基类对象的基类指针,无输出!
b1.foo(); // 毋庸置疑,调用父类自身的 Base::foo()
b1.fun(); // 毋庸置疑,调用父类自身的 Base::fun()
b1.bar(); // 毋庸置疑,调用父类自身的 Base::bar()
b2->foo(); // 同理,调用父类自身的 Base::foo()
b2->fun(); // 同理,调用父类自身的 Base::fun()
b2->bar(); // 同理,调用父类自身的 Base::bar()
fun1(&b1); // 输出 void fun1(Base * base)
fun1(b2); // 输出 void fun1(Base * base)
//fun2(&b1); // 转换失败,语法错误
fun2(static_cast<Derive *>(&b1)); // 应该用 static_cast<Derive *>,输出 void fun2(Derive * derive)
//fun2(b2); // 转换失败
fun2(static_cast<Derive *>(b2)); // 同理,输出 void fun2(Derive * derive)
} // 到达作用域尾,析构,输出 Base::destruct
std::cout << "\n\n----------------------------\n\n";
// 测试二:基类指针指向子类成员
{
Derive d; // 新建子类对象,先调用基类的构造函数 Base::construct,再调用自身的构造函数 Derive::construct
Base *b = &d; // 指向子类对象的基类指针,无输出!
d.foo(); // 毋庸置疑,Derive::foo()
d.fun(); // Derive::fun()
d.bar(); // Derive::bar()
b->foo(); // 构成多态,输出 Derive::foo()
b->fun(); // 不是多态,Base::fun()
b->bar(); // 不是多态,Base::bar(),说明 virtual 修饰子类的成员函数时不影响父类指针的执行
fun1(&d); // 子类地址复制给父类指针,输出 void fun1(Base * base)
fun1(b); // void fun1(Base * base)
fun2(&d); // void fun2(Derive * derive)
//fun2(b); // 转换失败
fun2(static_cast<Derive *>(b)); // void fun2(Derive * derive)
} // 离开作用域,先析构子类 Derive::destruct,再析构父类 Base::destruct
std::cout << "\n\n----------------------------\n\n";
// 测试三:子类指针指向基类成员
{
Base b; // 新建父类对象,输出 Base::construct,
//Derive * d = &b; // 语法错误,也就是说父类对象的地址不能赋值给子类指针
Derive *d = (Derive *)&b; // 正确姿势
b.foo(); // Base::foo()
b.fun(); // Base::fun()
b.bar(); // Base::bar()
d->foo(); // 子类指针指向父类,无法构成多态,依旧调用父类的方法,Base::foo()
d->fun(); // 普通成员函数,Derive::fun()
//d->bar(); // 行为未定义,想想为什么???
fun1(&b); // void fun1(Base * base)
fun1(d); // void fun1(Base * base)
//fun2(&b); // 转换失败
fun2(static_cast<Derive *>(&b)); // void fun2(Derive * derive)
fun2(d); // void fun2(Derive * derive)
} // Base::destruct
std::cout << "\n\n----------------------------\n\n";
// 测试四:子类指针指向子类
{
Derive d1; // Base::construct Derive::construct
Derive *d2 = &d1; // 无输出
d1.foo(); //Derive::foo()
d1.fun(); // Derive::fun()
d1.bar(); // Derive::bar()
d2->foo(); // Derive::foo()
d2->fun(); // Derive::fun()
d2->bar(); // Derive::bar()
fun1(&d1); // void fun1(Base * base)
fun1(d2); // void fun1(Base * base)
fun2(&d1); // void fun2(Derive * derive)
fun2(d2); // void fun2(Derive * derive)
} // Derive::destruct Base::destruct
return 0;
}
学海无涯 …