C++笔记之基类指针动态地指向某一个子类情况列举
code review!
文章目录
- C++笔记之基类指针动态地指向某一个子类情况列举
- 1.基本的多态示例
- 2.基类中的成员函数可以设置为纯虚函数
- 3.将基本示例修改为使用智能指针并在堆上实例化子类
- 4.父类指针指向基类后,可以去调用只有子类才有的成员函数吗?
- 5.子类和基类的构造函数之间的关系
- 6.若子类和基类的构造函数不同情况一(没有用虚函数)
- 7.若子类和基类的构造函数不同情况二(没有用虚函数)
- 8.若子类和基类的构造函数不同情况三(修改情况二的代码为堆上实例化,使用虚函数)
- 9.C++中的构造函数(constructor)不能被声明为虚函数。
- 10.C++中基类指针动态地指向某一个子类(结合switch使用)情况一
- 11.C++中基类指针动态地指向某一个子类(结合switch使用)情况二,使用智能指针
- 12.C++中基类指针动态地指向某一个子类(结合switch使用)情况三,在switch前就在堆上实例化
- 13.C++中基类指针动态地指向某一个子类(结合switch使用)情况三,在switch前就在堆上实例化,使用智能指针和std::move
1.基本的多态示例
代码
#include <iostream>class Base {
public:virtual void display() {std::cout << "This is the Base class." << std::endl;}
};class Derived1 : public Base {
public:void display() override {std::cout << "This is Derived1." << std::endl;}
};class Derived2 : public Base {
public:void display() override {std::cout << "This is Derived2." << std::endl;}
};int main() {Base* ptr;Derived1 derived1;Derived2 derived2;ptr = &derived1;ptr->display(); // 输出:This is Derived1.ptr = &derived2;ptr->display(); // 输出:This is Derived2.return 0;
}
2.基类中的成员函数可以设置为纯虚函数
3.将基本示例修改为使用智能指针并在堆上实例化子类
代码
#include <iostream>
#include <memory>class Base {
public:virtual void display() {std::cout << "This is the Base class." << std::endl;}virtual ~Base() {} // Virtual destructor to ensure proper cleanup
};class Derived1 : public Base {
public:void display() override {std::cout << "This is Derived1." << std::endl;}
};class Derived2 : public Base {
public:void display() override {std::cout << "This is Derived2." << std::endl;}
};int main() {std::unique_ptr<Base> ptr;ptr = std::make_unique<Derived1>();ptr->display(); // 输出:This is Derived1.ptr = std::make_unique<Derived2>();ptr->display(); // 输出:This is Derived2.return 0;
}
4.父类指针指向基类后,可以去调用只有子类才有的成员函数吗?
5.子类和基类的构造函数之间的关系
6.若子类和基类的构造函数不同情况一(没有用虚函数)
代码
#include <iostream>class Base {
private:int baseValue;public:Base(int value) : baseValue(value) {std::cout << "Base constructor with value: " << baseValue << std::endl;}void display() {std::cout << "Base value: " << baseValue << std::endl;}
};class Derived : public Base {
private:int derivedValue;public:// 子类构造函数调用基类构造函数,然后初始化子类成员Derived(int baseVal, int derivedVal) : Base(baseVal), derivedValue(derivedVal) {std::cout << "Derived constructor with values: " << baseVal << ", " << derivedVal << std::endl;}void display() {Base::display(); // 调用基类的 display 函数std::cout << "Derived value: " << derivedValue << std::endl;}
};int main() {Derived derived(10, 20);derived.display();return 0;
}
7.若子类和基类的构造函数不同情况二(没有用虚函数)
代码
#include <iostream>class Base {
private:int baseValue;public:Base() : baseValue(0) {std::cout << "Base default constructor" << std::endl;}void display() {std::cout << "Base value: " << baseValue << std::endl;}
};class Derived : public Base {
private:int derivedValue;public:// 子类构造函数有参数,调用基类默认构造函数,然后初始化子类成员Derived(int derivedVal) : Base(), derivedValue(derivedVal) {std::cout << "Derived constructor with value: " << derivedVal << std::endl;}void display() {Base::display(); // 调用基类的 display 函数std::cout << "Derived value: " << derivedValue << std::endl;}
};int main() {Derived derived(20);derived.display();return 0;
}
8.若子类和基类的构造函数不同情况三(修改情况二的代码为堆上实例化,使用虚函数)
运行
代码
#include <iostream>class Base {
private:int baseValue;public:Base() : baseValue(0) {std::cout << "Base default constructor" << std::endl;}virtual ~Base() {std::cout << "Base destructor" << std::endl;}virtual void display() {std::cout << "Base value: " << baseValue << std::endl;}
};class Derived : public Base {
private:int derivedValue;public:// 子类构造函数有参数,调用基类默认构造函数,然后初始化子类成员Derived(int derivedVal) : Base(), derivedValue(derivedVal) {std::cout << "Derived constructor with value: " << derivedVal << std::endl;}~Derived() {std::cout << "Derived destructor" << std::endl;}void display() {Base::display(); // 调用基类的 display 函数std::cout << "Derived value: " << derivedValue << std::endl;}
};int main() {Base* ptr = new Derived(20);ptr->display();delete ptr;return 0;
}
9.C++中的构造函数(constructor)不能被声明为虚函数。
10.C++中基类指针动态地指向某一个子类(结合switch使用)情况一
运行
代码
#include <iostream>class Base {
public:virtual void display() {std::cout << "This is the Base class." << std::endl;}
};class Derived1 : public Base {
public:void display() override {std::cout << "This is Derived1." << std::endl;}
};class Derived2 : public Base {
public:void display() override {std::cout << "This is Derived2." << std::endl;}
};int main() {int choice;Base* ptr = nullptr;std::cout << "Enter your choice (1 for Derived1, 2 for Derived2): ";std::cin >> choice;switch (choice) {case 1:ptr = new Derived1;break;case 2:ptr = new Derived2;break;default:std::cout << "Invalid choice." << std::endl;return 1;}if (ptr) {ptr->display();delete ptr;}return 0;
}
11.C++中基类指针动态地指向某一个子类(结合switch使用)情况二,使用智能指针
运行
代码
#include <iostream>
#include <memory> // 包含智能指针所需的头文件class Base {public:virtual void display() {std::cout << "This is the Base class." << std::endl;}
};class Derived1 : public Base {public:void display() override {std::cout << "This is Derived1." << std::endl;}
};class Derived2 : public Base {public:void display() override {std::cout << "This is Derived2." << std::endl;}
};int main() {int choice;std::cout << "Enter your choice (1 for Derived1, 2 for Derived2): ";std::cin >> choice;std::unique_ptr<Base> ptr; // 使用 std::unique_ptr 来替代原始指针switch (choice) {case 1:ptr = std::make_unique<Derived1>(); // 使用 std::make_unique 创建实例break;case 2:ptr = std::make_unique<Derived2>(); // 使用 std::make_unique 创建实例break;default:std::cout << "Invalid choice." << std::endl;return 1;}ptr->display();// 不再需要手动删除,unique_ptr 会在作用域结束时自动释放内存return 0;
}
12.C++中基类指针动态地指向某一个子类(结合switch使用)情况三,在switch前就在堆上实例化
代码
#include <iostream>class Base {
public:virtual void display() {std::cout << "This is the Base class." << std::endl;}
};class Derived1 : public Base {
public:void display() override {std::cout << "This is Derived1." << std::endl;}
};class Derived2 : public Base {
public:void display() override {std::cout << "This is Derived2." << std::endl;}
};int main() {Derived1* derived1 = new Derived1();Derived2* derived2 = new Derived2();int choice;std::cout << "Enter your choice (1 for Derived1, 2 for Derived2): ";std::cin >> choice;Base* ptr = nullptr;switch (choice) {case 1:ptr = derived1;break;case 2:ptr = derived2;break;default:std::cout << "Invalid choice." << std::endl;delete derived1;delete derived2;return 1;}ptr->display();delete derived1;delete derived2;return 0;
}
13.C++中基类指针动态地指向某一个子类(结合switch使用)情况三,在switch前就在堆上实例化,使用智能指针和std::move
运行
代码
#include <iostream>
#include <memory> // 包含智能指针所需的头文件class Base {public:virtual void display() {std::cout << "This is the Base class." << std::endl;}
};class Derived1 : public Base {public:void display() override {std::cout << "This is Derived1." << std::endl;}
};class Derived2 : public Base {public:void display() override {std::cout << "This is Derived2." << std::endl;}
};int main() {std::unique_ptr<Derived1> derived1 = std::make_unique<Derived1>();std::unique_ptr<Derived2> derived2 = std::make_unique<Derived2>();int choice;std::cout << "Enter your choice (1 for Derived1, 2 for Derived2): ";std::cin >> choice;std::unique_ptr<Base> ptr;switch (choice) {case 1:ptr = std::move(derived1); // 使用 std::move 进行所有权转移break;case 2:ptr = std::move(derived2); // 使用 std::move 进行所有权转移break;default:std::cout << "Invalid choice." << std::endl;return 1;}ptr->display();return 0; // 在作用域结束时,智能指针会自动释放内存
}