一、类的基本定义
1.1 类的基本结构
// 类的完整定义示例
class Student {
// 访问控制
private:
// 私有数据成员
std::string name;
int age;
double gpa;
static int totalStudents; // 静态成员变量
protected:
// 受保护成员
int studentId;
public:
// 公有成员函数
// 构造函数
Student(); // 默认构造函数
Student(const std::string& n, int a); // 参数化构造函数
Student(const Student& other); // 拷贝构造函数
Student(Student&& other) noexcept; // 移动构造函数
// 析构函数
~Student();
// 成员函数
void display() const; // const成员函数
void setGpa(double g);
double getGpa() const { return gpa; } // 内联函数
// 运算符重载
Student& operator=(const Student& other); // 拷贝赋值
Student& operator=(Student&& other) noexcept; // 移动赋值
bool operator==(const Student& other) const;
// 静态成员函数
static int getTotalStudents() { return totalStudents; }
// 友元声明
friend std::ostream& operator<<(std::ostream& os, const Student& s);
friend class Teacher; // 友元类
};
// 静态成员变量定义
int Student::totalStudents = 0;
1.2 访问控制详解
class AccessControl {
private:
// 只能被类的成员函数和友元访问
int privateData;
void privateMethod() {}
protected:
// 可以被类的成员函数、友元和派生类访问
int protectedData;
void protectedMethod() {}
public:
// 可以被任何代码访问
int publicData;
void publicMethod() {}
// 嵌套类的访问控制
class NestedPublic {
public:
void accessOuter(AccessControl& ac) {
ac.privateData = 10; // 嵌套类可以访问外部类的私有成员
}
};
private:
class NestedPrivate {
// 私有嵌套类
};
};
// struct 默认是 public,class 默认是 private
struct StructExample {
int x; // 默认 public
};
class ClassExample {
int x; // 默认 private
};
二、构造函数详解
2.1 各种构造函数类型
class ConstructorDemo {
private:
int* data;
size_t size;
std::string name;
public:
// 1. 默认构造函数
ConstructorDemo() : data(nullptr), size(0), name("default") {
std::cout << "Default constructor called\n";
}
// 2. 参数化构造函数(带默认参数)
explicit ConstructorDemo(size_t s, const std::string& n = "unnamed")
: size(s), name(n) {
data = new int[size](); // 值初始化
std::cout << "Parameterized constructor called\n";
}
// 3. 委托构造函数 (C++11)
ConstructorDemo(int value) : ConstructorDemo(1, "single") {
data[0] = value;
std::cout << "Delegating constructor called\n";
}
// 4. 拷贝构造函数
ConstructorDemo(const ConstructorDemo& other)
: size(other.size), name(other.name) {
data = new int[size];
std::copy(other.data, other.data + size, data);
std::cout << "Copy constructor called\n";
}
// 5. 移动构造函数 (C++11)
ConstructorDemo(ConstructorDemo&& other) noexcept
: data(std::exchange(other.data, nullptr))
, size(std::exchange(other.size, 0))
, name(std::move(other.name)) {
std::cout << "Move constructor called\n";
}
// 6. 初始化列表构造函数
ConstructorDemo(std::initializer_list<int> init)
: size(init.size()), name("from_list") {
data = new int[size];
std::copy(init.begin(), init.end(), data);
std::cout << "Initializer list constructor called\n";
}
// 析构函数
~ConstructorDemo() {
delete[] data;
std::cout << "Destructor called for " << name << "\n";
}
};
// 使用示例
void constructorExamples() {
ConstructorDemo obj1; // 默认构造
ConstructorDemo obj2(10); // 委托构造
ConstructorDemo obj3(5, "custom"); // 参数化构造
ConstructorDemo obj4(obj3); // 拷贝构造
ConstructorDemo obj5(std::move(obj4)); // 移动构造
ConstructorDemo obj6{1, 2, 3, 4, 5}; // 初始化列表构造
}
2.2 成员初始化列表
class InitializationList {
private:
const int id; // const成员必须在初始化列表中初始化
int& ref; // 引用成员必须在初始化列表中初始化
std::string name;
static int counter; // 静态成员不在初始化列表中
// 成员类
class Inner {
int value;
public:
Inner(int v) : value(v) {}
};
Inner inner;
public:
// 初始化顺序:按照成员声明的顺序,而不是初始化列表的顺序
InitializationList(int i, int& r, const std::string& n)
: id(i) // const成员初始化
, ref(r) // 引用成员初始化
, name(n) // 普通成员初始化
, inner(100) // 成员对象初始化
{
// 构造函数体
// 此时所有成员已经初始化完成
}
// C++11 成员初始化器
class ModernInit {
int x = 10; // 类内初始化
double y{3.14}; // 统一初始化
std::string s{"hello"}; // 统一初始化
std::vector<int> vec{1, 2, 3, 4, 5};
public:
ModernInit() = default; // 使用默认值
ModernInit(int val) : x(val) {} // 覆盖默认值
};
};
三、对象创建方式
3.1 栈上创建对象
class StackObject {
private:
int data;
public:
StackObject(int d) : data(d) {
std::cout << "Stack object created\n";
}
~StackObject() {
std::cout << "Stack object destroyed\n";
}
};
void stackCreation() {
// 1. 直接初始化
StackObject obj1(10);
// 2. 拷贝初始化
StackObject obj2 = StackObject(20);
// 3. 统一初始化 (C++11)
StackObject obj3{30};
StackObject obj4 = {40};
// 4. 自动类型推导 (C++17)
auto obj5 = StackObject(50);
// 5. 数组创建
StackObject arr[3] = {
StackObject(1),
StackObject(2),
StackObject(3)
};
// 对象生命周期:函数结束时自动销毁
}
3.2 堆上创建对象
class HeapObject {
private:
std::string* data;
public:
HeapObject(const std::string& s) {
data = new std::string(s);
std::cout << "Heap object created: " << *data << "\n";
}
~HeapObject() {
delete data;
std::cout << "Heap object destroyed\n";
}
// 禁止栈上创建(仅堆上创建)
static HeapObject* create(const std::string& s) {
return new HeapObject(s);
}
private:
// 私有析构函数版本(需要提供销毁方法)
// ~HeapObject() { delete data; }
public:
void destroy() { delete this; }
};
void heapCreation() {
// 1. 使用 new
HeapObject* ptr1 = new HeapObject("Hello");
delete ptr1;
// 2. 使用 new[] 创建数组
HeapObject* arr = new HeapObject[3]{
HeapObject("A"),
HeapObject("B"),
HeapObject("C")
};
delete[] arr;
// 3. placement new
char buffer[sizeof(HeapObject)];
HeapObject* ptr2 = new(buffer) HeapObject("Placement");
ptr2->~HeapObject(); // 显式调用析构函数
// 4. 智能指针管理(推荐)
auto ptr3 = std::make_unique<HeapObject>("Smart");
auto ptr4 = std::make_shared<HeapObject>("Shared");
}
四、特殊成员函数
4.1 五大特殊成员函数(Rule of Five)
class RuleOfFive {
private:
int* data;
size_t size;
public:
// 1. 构造函数
explicit RuleOfFive(size_t s) : size(s), data(new int[s]()) {
std::cout << "Constructor\n";
}
// 2. 析构函数
~RuleOfFive() {
delete[] data;
std::cout << "Destructor\n";
}
// 3. 拷贝构造函数
RuleOfFive(const RuleOfFive& other) : size(other.size) {
data = new int[size];
std::copy(other.data, other.data + size, data);
std::cout << "Copy Constructor\n";
}
// 4. 拷贝赋值运算符
RuleOfFive& operator=(const RuleOfFive& other) {
std::cout << "Copy Assignment\n";
if (this != &other) {
// Copy-and-swap idiom
RuleOfFive temp(other);
swap(temp);
}
return *this;
}
// 5. 移动构造函数
RuleOfFive(RuleOfFive&& other) noexcept
: data(std::exchange(other.data, nullptr))
, size(std::exchange(other.size, 0)) {
std::cout << "Move Constructor\n";
}
// 6. 移动赋值运算符
RuleOfFive& operator=(RuleOfFive&& other) noexcept {
std::cout << "Move Assignment\n";
if (this != &other) {
delete[] data;
data = std::exchange(other.data, nullptr);
size = std::exchange(other.size, 0);
}
return *this;
}
// 辅助函数
void swap(RuleOfFive& other) noexcept {
std::swap(data, other.data);
std::swap(size, other.size);
}
};
4.2 特殊成员函数的控制
class SpecialMemberControl {
public:
// 显式默认
SpecialMemberControl() = default;
SpecialMemberControl(const SpecialMemberControl&) = default;
// 显式删除
SpecialMemberControl& operator=(const SpecialMemberControl&) = delete;
// 单例模式示例
class Singleton {
private:
Singleton() = default;
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
public:
static Singleton& getInstance() {
static Singleton instance;
return instance;
}
};
// 仅移动类型
class MoveOnly {
public:
MoveOnly() = default;
MoveOnly(const MoveOnly&) = delete;
MoveOnly& operator=(const MoveOnly&) = delete;
MoveOnly(MoveOnly&&) = default;
MoveOnly& operator=(MoveOnly&&) = default;
};
};
五、对象的生命周期管理
5.1 对象生命周期
class LifecycleDemo {
std::string name;
public:
LifecycleDemo(const std::string& n) : name(n) {
std::cout << name << " constructed\n";
}
~LifecycleDemo() {
std::cout << name << " destroyed\n";
}
};
class LifecycleManager {
public:
// 临时对象
void temporaryObjects() {
std::cout << "Creating temporary\n";
LifecycleDemo("temp"); // 立即销毁
std::cout << "Temporary destroyed\n";
// 延长临时对象生命周期
const LifecycleDemo& ref = LifecycleDemo("extended");
std::cout << "Still alive\n";
// ref 作用域结束时销毁
}
// 静态对象
void staticObjects() {
static LifecycleDemo staticObj("static"); // 程序结束时销毁
// 只初始化一次
}
// 全局对象
LifecycleDemo global("global"); // main之前构造,main之后销毁
};
六、高级类设计技巧
6.1 CRTP(奇异递归模板模式)
template<typename Derived>
class Base {
public:
void interface() {
static_cast<Derived*>(this)->implementation();
}
static void staticInterface() {
Derived::staticImplementation();
}
};
class Derived : public Base<Derived> {
public:
void implementation() {
std::cout << "Derived implementation\n";
}
static void staticImplementation() {
std::cout << "Derived static implementation\n";
}
};
6.2 Pimpl(指向实现的指针)惯用法
// Widget.h
class Widget {
class Impl; // 前向声明
std::unique_ptr<Impl> pImpl;
public:
Widget();
~Widget(); // 必须在源文件中定义
Widget(Widget&&);
Widget& operator=(Widget&&);
void doSomething();
};
// Widget.cpp
class Widget::Impl {
int data;
std::string name;
public:
void doSomething() {
// 实现细节
}
};
Widget::Widget() : pImpl(std::make_unique<Impl>()) {}
Widget::~Widget() = default; // 必须在Impl完整定义后
Widget::Widget(Widget&&) = default;
Widget& Widget::operator=(Widget&&) = default;
void Widget::doSomething() {
pImpl->doSomething();
}
6.3 工厂模式创建对象
class Product {
public:
virtual ~Product() = default;
virtual void use() = 0;
};
class ConcreteProductA : public Product {
public:
void use() override {
std::cout << "Using Product A\n";
}
};
class ConcreteProductB : public Product {
public:
void use() override {
std::cout << "Using Product B\n";
}
};
class Factory {
public:
enum class ProductType { A, B };
// 简单工厂
static std::unique_ptr<Product> createProduct(ProductType type) {
switch(type) {
case ProductType::A:
return std::make_unique<ConcreteProductA>();
case ProductType::B:
return std::make_unique<ConcreteProductB>();
default:
return nullptr;
}
}
// 注册式工厂
using Creator = std::function<std::unique_ptr<Product>()>;
static void registerProduct(const std::string& name, Creator creator) {
creators()[name] = creator;
}
static std::unique_ptr<Product> createProduct(const std::string& name) {
auto it = creators().find(name);
if (it != creators().end()) {
return it->second();
}
return nullptr;
}
private:
static std::map<std::string, Creator>& creators() {
static std::map<std::string, Creator> instance;
return instance;
}
};
// 自动注册
struct AutoRegister {
AutoRegister(const std::string& name) {
Factory::registerProduct(name, []() {
return std::make_unique<ConcreteProductA>();
});
}
};
七、对象内存布局
7.1 对象内存布局分析
class MemoryLayout {
// 内存对齐示例
class AlignmentExample {
char c; // 1 byte
// padding: 3 bytes
int i; // 4 bytes
char c2; // 1 byte
// padding: 7 bytes (假设8字节对齐)
double d; // 8 bytes
}; // 总大小: 24 bytes
// 优化后的布局
class OptimizedLayout {
double d; // 8 bytes
int i; // 4 bytes
char c; // 1 byte
char c2; // 1 byte
// padding: 2 bytes
}; // 总大小: 16 bytes
// 虚函数表
class VirtualClass {
virtual void func1() {}
virtual void func2() {}
int data;
}; // 包含vptr指针
public:
void printSizes() {
std::cout << "AlignmentExample: " << sizeof(AlignmentExample) << "\n";
std::cout << "OptimizedLayout: " << sizeof(OptimizedLayout) << "\n";
std::cout << "VirtualClass: " << sizeof(VirtualClass) << "\n";
}
};