簡體   English   中英

使用一個 function 調用 C++ 初始化多個常量 class 成員

[英]Initialize multiple constant class members using one function call C++

如果我有兩個不同的常量成員變量,它們都需要基於相同的 function 調用進行初始化,有沒有辦法在不調用 function 兩次的情況下做到這一點?

例如,分數 class,其中分子和分母是常數。

int gcd(int a, int b); // Greatest Common Divisor
class Fraction {
public:
    // Lets say we want to initialize to a reduced fraction
    Fraction(int a, int b) : numerator(a/gcd(a,b)), denominator(b/gcd(a,b))
    {

    }
private:
    const int numerator, denominator;
};

這會浪費時間,因為 GCD function 被調用了兩次。 您還可以定義一個新的 class 成員gcd_a_b ,然后首先將 gcd 的 output 分配給初始化列表中的那個,但這會導致浪費 ZCD69B4957F06CD829D7BF3D61980。

一般來說,有沒有辦法在不浪費 function 調用或 memory 的情況下做到這一點? 你可以在初始化列表中創建臨時變量嗎?

一般來說,有沒有辦法在不浪費 function 調用或 memory 的情況下做到這一點?

是的。 這可以通過 C++11 中介紹的委托構造函數來完成。

委托構造函數是在初始化任何成員變量之前獲取構造所需的臨時值的一種非常有效的方法。

int gcd(int a, int b); // Greatest Common Divisor

class Fraction {
public:
    // Call gcd ONCE, and forward the result to another constructor.
    Fraction(int a, int b) : Fraction(a,b,gcd(a,b))
    {
    }
private:
    // This constructor is private, as it is an
    // implementation detail and not part of the public interface.
    Fraction(int a, int b, int g_c_d) : numerator(a/g_c_d), denominator(b/g_c_d)
    {
    }
    const int numerator, denominator;
};

成員變量按它們在 class 聲明中聲明的順序進行初始化,因此您可以執行以下操作(數學上)

#include <iostream>
int gcd(int a, int b){return 2;}; // Greatest Common Divisor of (4, 6) just to test
class Fraction {
public:
    // Lets say we want to initialize to a reduced fraction
    Fraction(int a, int b) : numerator{a/gcd(a,b)}, denominator(b/(a/numerator))
    {    
    }
//private:
    const int numerator, denominator;//make sure that they are in this order
};
//Test
int main(){
    Fraction f{4,6};
    std::cout << f.numerator << " / " << f.denominator;
}

無需調用其他構造函數,甚至無需制作它們。

@Drew Dormann 給出了一個類似於我的想法的解決方案。 由於 OP 從未提及無法修改 ctor,因此可以使用Fraction f {a, b, gcd(a, b)}調用它:

Fraction(int a, int b, int tmp): numerator {a/tmp}, denominator {b/tmp}
{
}

只有這樣,才不會再次調用 function、構造函數或其他方法,因此不會浪費時間。 而且它不會浪費 memory 因為無論如何都必須創建一個臨時的,所以你不妨好好利用它。 它還避免了額外的划分。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM