在构造函数中设置公共类变量

时间:2015-01-13 11:55:38

标签: c++ class variables

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

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

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

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("...");
    }
}

4 个答案:

答案 0 :(得分:3)

您正在做的事情很好。

有些人可能会声称Foo::alpha看起来像是一个静态成员,因此可能会让人感到困惑,但我对此的反应是,这样的人只会这么认为,因为他们不了解C ++。

Foo::alpha明确指出班级alpha中的成员Foo;由于您是成员函数,该成员可以(并且是)非static成员。

this->alpha或重命名构造函数参数会更常规,但你正在做的事情很好。

答案 1 :(得分:3)

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

#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使用不同的名称,但语言不需要它。

答案 2 :(得分:1)

您只需使用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:: 通常用于访问静态变量或方法,或者在实现过程中引用类的方法。您的代码不正确,但通常不会用于初始化非静态成员公共变量。

答案 3 :(得分:0)

没错。它不漂亮。当构造函数的参数与类中的数据成员具有相同的名称时,您有以下几个选项:

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("...");
}