根据创建的实例对象而决定,如果实例对象是const则自动调第二个,如果非const调用第一个。
析构函数不可以重载。 析构函数不重载,可能导致父类资源无法释放。 构造函数的调用顺序是,先构造父类,再构造子类。析构函数的顺序是反过来的,先析构子类,再析构父类。
#include <iostream>
class Base {
public:
Base() {
std::cout << "Base constructor called." << std::endl;
}
// 注意:这里没有将析构函数声明为虚函数
~Base() {
std::cout << "Base destructor called." << std::endl;
}
};
class Derived : public Base {
public:
Derived() {
std::cout << "Derived constructor called." << std::endl;
}
~Derived() {
std::cout << "Derived destructor called." << std::endl;
}
};
int main() {
Base* ptr = new Derived(); // 创建一个Derived对象,并用Base指针指向它
delete ptr; // 通过基类指针删除对象
return 0;
}
// 如果析构不是虚函数,那么只会释放父类的资源,而泄露了子类的资源
如果想要将父类转换为子类,需要父类中至少有一个虚函数,dynmic_cast依赖于运行时类型信息(RTTI),因此需要虚函数的存在。
## #include <iostream>
#include <exception>
class Base {
public:
virtual ~Base() {} // 基类需要至少一个虚函数(通常是析构函数),以支持RTTI
};
class Derived1 : public Base {
public:
void derived1Function() {
std::cout << "Derived1 function called." << std::endl;
}
};
class Derived2 : public Base {
public:
void derived2Function() {
std::cout << "Derived2 function called." << std::endl;
}
};
int main() {
Base* basePtr1 = new Derived1();
Base* basePtr2 = new Derived2();
// 尝试将 basePtr1 转换为 Derived1*
Derived1* derivedPtr1 = dynamic_cast<Derived1*>(basePtr1);
if (derivedPtr1) {
derivedPtr1->derived1Function();
} else {
std::cout << "Conversion to Derived1 failed." << std::endl;
}
// 尝试将 basePtr2 转换为 Derived1*(应该失败)
Derived1* derivedPtr2 = dynamic_cast<Derived1*>(basePtr2);
if (derivedPtr2) {
derivedPtr2->derived1Function();
} else {
std::cout << "Conversion to Derived1 failed (as expected)." << std::endl;
}
// 清理内存
delete basePtr1;
delete basePtr2;
return 0;
}
静态成员函数只能访问静态成员变量。静态成员变量在所有对象中共享。
想要malloc和new时,不用显式分配内存和管理内存,就可以使用智能指针。