一般來說,假設我以這種方式定義自己的建構式:
class Numbers
{
public:
Numbers(int a, int b);
}
我是否必須:
定義一個新的默認建構式?我知道一旦我定義了自己的建構式,默認建構式就不再存在,但我不知道是否有必要/建議包含一個
類中需要包含引數嗎?即我應該添加:
class Numbers { private: int ma; int mb; };
先感謝您!
uj5u.com熱心網友回復:
對于非常簡單的結構/類,您始終可以嘗試將它們撰寫為聚合。基本上:
- 不要使用私有或受保護的成員。
- 不要用戶提供建構式。
然后享受:
- 結構/類的最少宣告。
- 簡單的直接串列初始化。
[演示]
#include <iostream> // cout
#include <ostream>
struct Numbers // minimal declaration
{
int ma{};
int mb{};
};
std::ostream& operator<<(std::ostream& os, const Numbers& ns)
{
return os << "(" << ns.ma << ", " << ns.mb << ")";
}
int main()
{
Numbers ns{10, 20}; // direct-list-initialization
std::cout << ns << "\n";
}
uj5u.com熱心網友回復:
這由你來決定。在大多數情況下,默認建構式可以很方便,并使生活更輕松。但是,如果您希望班級的用戶始終提供數字,那也沒關系。
是的,如果你想要屬性,你需要宣告它們。C 不會從建構式引數中神奇地推匯出它們
uj5u.com熱心網友回復:
如果給定的類不包含建構式,則在編譯時會自動創建 2 個建構式。
1 - 默認建構式 2 - 復制建構式
如果您創建一個默認建構式,那么自動創建的建構式將被您的建構式替換。
uj5u.com熱心網友回復:
這取決于你如何使用你的class Numbers.
建構式可用于:
- 分配資源。
- 強制類的用戶以某種方式初始化物件。
- 檢查將初始化物件的引數,然后允許/避免創建具有特定狀態(成員變數)的物件。
- ...
例如,如果您有一個class date,該類可以實作建構式來檢查我們作為引數傳遞的日、月和年。
class date final {
public:
constexpr date(const int d, const int m, const int y) : d(d), m(m), y(y) {
// Check if the object has a valid state (valid values)
// e.g: Is d equal to 0? Is m greater than 12? If yes throw an exception
}
constexpr auto day () const noexcept { return d; }
constexpr auto month () const noexcept { return m; }
constexpr auto day () const noexcept { return y; }
private:
int d, m, y;
};
如果一個類的用戶忘記初始化一個物件,編譯器就會報錯。如果物件用錯誤的值初始化,編譯時可以檢查,編譯器會報錯,如果編譯時不能檢查,則執行時拋出例外。
date如果可以date使用有效值和默認值初始化物件,則可以實作默認構造函式(在這種情況下,默認概念是主觀的)。
class date final {
public:
constexpr date() noexcept : d(1), m(1), y(2001) { } // The first day of the current century, for example.
constexpr date(const int d, const int m, const int y) : d(d), m(m), y(y) {
// Check if the object has a valid state (valid values)
// e.g: Is d equal to 0? Is m greater than 12? If yes throw an exception
}
constexpr auto day () const noexcept { return d; }
constexpr auto month () const noexcept { return m; }
constexpr auto day () const noexcept { return y; }
private:
int d, m, y;
};
(上面的例子類似于“編程:使用 C 的原則和實踐”一書中的例子)。
因此,建構式和訪問修飾符允許您實作對類成員的檢查訪問。我們可以使用它來建立一個不變數(必須滿足的條件 - 必須為真 - 例如:日期的月份必須在 [1:12] - 包含 - 之間)。
通過回答你的問題,在你需要的時候使用建構式,它們對你正在做的事情很有用,當你實作建構式時,問問自己為什么要這樣做。
使用默認建構式作為你的建構式,如果你能提供默認和有效值,實作一個默認建構式,這樣,如果用戶不需要用特定的值初始化物件,他可以使用你的建構式提供的值。
對不起我的英語不好。
我希望這會幫助你,我希望有人能幫助我回答我的問題,我也是初學者。xD
編輯 :
您將在沒有建構式的情況下實作并且可能不需要面向物件的方法的“類”示例。
struct vector2 {
int x, y;
static constexpr auto empty() noexcept { return vector2{ 0, 0 }; }
constexpr auto operator (const vector2& other) const noexcept { return vector2{ x other.x, y other.y }; }
constexpr auto operator-(const vector2& other) const noexcept { return vector2{ x - other.x, y - other.y }; }
constexpr auto operator==(const vector2& other) const noexcept { return x == other.x && y == other.y; }
constexpr auto operator!=(const vector2& other) const noexcept { return !(*this == other); }
constexpr auto is_empty() const noexcept { return *this == empty(); }
};
或使用運算子作為“自由運算子”(結構外)
在這個例子中,我不使用建構式,也不使用訪問修飾符,因為“類”很簡單,而且我沒有為成員變數建立任何不變數(我可以實作“類”以確保 x 和 y 的值不是負,例如)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/388764.html
上一篇:回傳特征矩陣和臨時值
