类与对象
翻译整理自 cppreference - 类。
1. 定义类
class Point {
public:
Point(int x, int y) : x_(x), y_(y) {} // 构造函数
int x() const { return x_; }
int y() const { return y_; }
private:
int x_, y_;
};
Point p(1, 2);
std::cout << p.x();struct 默认公开成员,class 默认私有,其他完全一致。
2. 构造函数
class Foo {
public:
Foo() = default; // 默认构造
Foo(int x) : x_(x) {} // 普通构造
Foo(const Foo&) = delete; // 禁止拷贝
Foo(Foo&&) noexcept = default; // 默认移动
Foo(int x, int y) : x_(x), y_(y) {} // 多参数
private:
int x_ = 0, y_ = 0;
};委托构造(C++11)
class Foo {
public:
Foo() : Foo(0) {}
Foo(int x) : x_(x) {}
private:
int x_;
};explicit 防隐式转换
class String {
public:
explicit String(const char* s);
};
String s1 = "x"; // ❌ explicit 禁止
String s2("x"); // OK
3. 析构函数
class Buffer {
public:
Buffer(size_t n) : data_(new char[n]) {}
~Buffer() { delete[] data_; } // 释放
private:
char* data_;
};如果类管理资源,应遵循三/五法则:
- 三:定义析构 + 拷贝构造 + 拷贝赋值
- 五(C++11):加上移动构造 + 移动赋值
或更推荐零法则:使用 RAII 容器(如
std::vector、std::unique_ptr),让编译器自动生成。
4. 拷贝与移动
class V {
public:
V() = default;
V(const V&) = default; // 拷贝构造
V& operator=(const V&) = default; // 拷贝赋值
V(V&&) noexcept = default; // 移动构造
V& operator=(V&&) noexcept = default; // 移动赋值
};
V a;
V b = a; // 拷贝
V c = std::move(a); // 移动
5. 访问控制
public:公开private:私有(仅本类与友元)protected:派生类可访问
class A {
public: int x;
protected: int y;
private: int z;
};friend 友元
class Account {
friend class Bank;
private:
int balance;
};
class Bank {
void view(Account& a) { std::cout << a.balance; }
};6. 静态成员
class Counter {
public:
static int count;
Counter() { ++count; }
};
int Counter::count = 0; // 定义
C++17 起 inline static 可就地初始化:
class Counter {
inline static int count = 0;
};7. this 指针
class Builder {
public:
Builder& setName(const std::string& n) {
name_ = n;
return *this; // 链式调用
}
private:
std::string name_;
};
Builder b;
b.setName("a");8. const 成员函数
class Vec {
public:
int size() const { return size_; } // const,不修改对象
};const 对象只能调用 const 成员函数。
9. mutable
允许 const 函数中修改:
class Cache {
public:
int compute() const {
if (cached_) return value_;
value_ = expensive();
cached_ = true;
return value_;
}
private:
mutable bool cached_ = false;
mutable int value_ = 0;
};10. 运算符重载
class Vec2 {
public:
Vec2(int x, int y) : x_(x), y_(y) {}
Vec2 operator+(const Vec2& r) const {
return Vec2{x_ + r.x_, y_ + r.y_};
}
int operator[](size_t i) const {
return i == 0 ? x_ : y_;
}
friend std::ostream& operator<<(std::ostream& os, const Vec2& v) {
return os << "(" << v.x_ << "," << v.y_ << ")";
}
private:
int x_, y_;
};
Vec2 a{1, 2}, b{3, 4};
std::cout << (a + b);11. 用户定义字面量(C++11)
constexpr long double operator""_deg(long double d) {
return d * 3.14159 / 180.0;
}
auto r = 90.0_deg;12. 类型转换运算符
class FilePath {
public:
operator std::string() const { return path_; }
private:
std::string path_;
};
std::string p = FilePath();显式转换避免误用:
explicit operator std::string() const;小结
C++ 类支持构造、析构、拷贝、移动、运算符重载、模板等,让用户类型像内置类型一样自然。