在构造函数中设置 public class 变量

Set public class variable in constructor

我想编写一个 public class 变量,其值在调用构造函数时给出。我有一个我认为是正确的解决方案,直到有人告诉我它可能是错误的(带有 "Foo::alpha = alpha;" 的行)。
所以当我 运行

Foo bar(g, 0);
bar.run();

然后我希望将值 0 写入 class 变量,以便稍后在 运行 方法中访问它。

Foo.h

class Foo: public Framework::Centrality {
public:
    double alpha;
    Foo(const Graph& G, double alpha=1);
    void run() override;
};

Foo.cpp

Foo::Foo(const Graph& G, double alpha) : Centrality(G) {
    if (alpha >= 0 && alpha <= 1) {
        Foo::alpha = alpha;
    } else {
        throw std::runtime_error("...");
    }
}

您可以简单地将值分配给 alpha 使用 this-> 而无需使用 Foo:::

Foo::Foo(const Graph& G, double alpha) : Centrality(G) {
    if (alpha >= 0 && alpha <= 1) {
        this->alpha = alpha;
    } else {
        throw std::runtime_error("...");
    }
}

Foo::通常用于访问静态变量或方法或在执行期间引用class的方法。您的代码没有错,但通常不用于初始化非静态成员 public 变量。

你做的很好。

有些人可能会说 Foo::alpha 看起来像是命名静态成员,因此可能会造成混淆,但我对此的回应是,这种人只会这么想,因为他们不懂 C++。

Foo::alpha 在 class Foo 中明确命名成员 alpha;由于您在成员函数中,该成员可以(并且是)非 static 成员。

编写 this->alpha 或重命名构造函数参数会更常规,但您所做的很好。

你所做的在技术上是正确的,但你真的应该为此使用成员初始化列表:

#include <stdexcept>

class Base {};

class Ace :  Base
{
  public:
    Ace(double alpha = 0) : Base(), alpha(alpha)
    {
      if(alpha < 0 || alpha > 1)
        throw std::runtime_error("");
    }
    double alpha;
}

您可以为构造函数参数使用不同的名称 alpha,但这不是语言所要求的。

没有错。它只是不漂亮。当构造函数的参数与 class 上的数据成员同名时,您有几个选择:

1) 使用成员初始值设定项列表,根据标准,它必须执行您打算在此处执行的操作:

Foo::Foo(const Graph& G, double alpha) :
    Centrality(G), alpha(alpha)
{
    if(alpha < 0 || alpha > 1)
        throw std::runtime_error("...");
}

2) 完全限定成员 alpha,正如您所做的那样:

Foo::Foo(const Graph& G, double alpha) :
    Centrality(G)
{
    if(alpha >= 0 && alpha <=1 )
        Foo::alpha = alpha;
    else
        throw std::runtime_error("...");
}

3) 使用this指针指定成员:

Foo::Foo(const Graph& G, double alpha) :
    Centrality(G)
{
    if(alpha >= 0 && alpha <=1 )
        this->alpha = alpha;
    else
        throw std::runtime_error("...");
}

4) 给它们起不同的名字。一个常见的约定是在数据成员的名称前加上 m 或 m_:

class Foo : public Framework::Centrality
{
    /* other stuff */

 private:
    double m_Alpha;
};


Foo::Foo(const Graph& G, double alpha) :
    Centrality(G)
{
    if(alpha >= 0 && alpha <=1 )
        m_Alpha = alpha;
    else
        throw std::runtime_error("...");
}

我看到的另一个常见的事情是在 cpp 中的参数前加上下划线:

class Foo : public Framework::Centraliy
{
    Foo(const Graph& G, double alpha=1);
};

Foo::Foo(const Graph& G, double _alpha) :
    Centrality(G)
{
    ...
}

5) 或者如果使用 pImpl 习语,(我喜欢将我的 Impl 成员命名为 m):

class Foo : public Framework::Centrality
{
    /* other stuff */

 private:
    struct Impl;
    std::unique_ptr<Impl> m;
};

// In foo.cpp
struct Foo::Impl
{
    double alpha;
}

Foo::Foo(const Graph& G, double alpha) :
    Centrality(G),
    m(make_unique<Impl>())
{
    if(alpha >= 0 && alpha <=1 )
        m->alpha = alpha;
    else
        throw std::runtime_error("...");
}