Truyền std::vector vào constructor của lớp để khởi tạo thành viên dữ liệu. Có 3 cách chính tùy ý đồ sở hữu và hiệu năng.
1. Truyền bằng const reference + copy (An toàn, phổ biến)
class MyClass {
vector<int> data_;
public:
MyClass(const vector<int>& v) : data_(v) {} // copy
// hoặc explicit MyClass(const vector<int>& v) : data_(v) {}
};
- Gọi copy constructor của vector – deep copy O(N).
- An toàn, caller giữ nguyên vector gốc.
2. Truyền bằng value + move (C++11 – Hiệu quả khi caller có temporary)
class MyClass {
vector<int> data_;
public:
MyClass(vector<int> v) : data_(std::move(v)) {} // move từ parameter
};
- Caller:
MyClass obj(vector<int>{1,2,3});(temporary) → 1 move. - Caller:
MyClass obj(myVec);(lvalue) → 1 copy vào param + 1 move vào member = 1 copy. - Tối ưu cho cả lvalue và rvalue.
3. Perfect Forwarding (C++11 – Linh hoạt nhất)
class MyClass {
vector<int> data_;
public:
template<typename Vec>
MyClass(Vec&& v) : data_(std::forward<Vec>(v)) {}
};
- Chấp nhận lvalue (copy) và rvalue (move) tự động.
- Cẩn thận: template constructor có thể match mọi thứ – dùng
enable_ifhoặc concepts (C++20) để hạn chế.
Ví dụ đầy đủ (Cách 2 – Khuyến nghị)
#include <iostream>
#include <vector>
#include <utility> // move
using namespace std;
class VectorHolder {
vector<int> vec_;
public:
// Pass by value + move
VectorHolder(vector<int> v) : vec_(std::move(v)) {}
void show() const {
for (int x : vec_) cout << x << ' ';
cout << endl;
}
};
int main() {
vector<int> v = {7, 6, 5, 4};
VectorHolder h1(v); // lvalue -> copy + move
VectorHolder h2(vector<int>{1,2,3}); // rvalue -> move + move (elided)
VectorHolder h3({4,5,6}); // initializer_list -> vector temp -> move
h1.show(); // 7 6 5 4
h2.show(); // 1 2 3
h3.show(); // 4 5 6
return 0;
}
Kết quả
7 6 5 4 1 2 3 4 5 6
So sánh nhanh
| Cách | Lvalue caller | Rvalue caller | Code complexity |
|---|---|---|---|
| const ref + copy | 1 copy | 1 copy | Thấp |
| by value + move | 1 copy + 1 move | 1 move (elided) | Thấp |
| Perfect forwarding | 1 copy | 1 move | Cao (template) |
Lưu ý
- Nếu class chỉ cần xem vector (không lưu) → dùng
const vector<T>&hoặcspan<T>(C++20). - Nếu cần chia sẻ sở hữu →
shared_ptr<vector<T>>. - Tránh truyền vector by value nếu không move vào member (gây copy thừa).