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; // 在作用域结束时,智能指针会自动释放内存
}