【问题标题】:Clean Instantiation of a Vector in the Base Class基类中向量的干净实例化
【发布时间】:2017-12-19 21:50:47
【问题描述】:

我正在编写 C++11 中的代码,并且与类构造和向量值相关的部分代码已经失控。我怎样才能使它更简洁?

我的工作与版本相关,并创建了一个std::vector<uint16_t> 类型的版本号向量来保存一个值数组来表示格式1.0.0.25 的版本。我希望所有类都有一个版本,所以我把它放在基类中。然后子代继承Base 并实例化版本。

目前,我的代码有一个 Version 类、一个 Base 类和一个 Child 类。开发人员将通过在 Child 类的定义变量中设置值来硬编码版本。我希望它易于查看和阅读。我的问题是 Child 类传递值的部分目前非常丑陋,我希望使其更简洁易读。

代码是:

#include <vector>

namespace CodeStuff
{
namespace VersionStuff
{


typedef uint16_t VersionType;

class Version
{

public:
    Version(const std::vector<VersionType> & aNumbers, const VersionType aType = -1)
    {
        numbers_ = aNumbers;
        type_ = aType;
    }
private:
    std::vector<VersionType> numbers_;
    VersionType type_;
};

} // end namespace VersionStuff
} // end namespace CodeStuff

class Base
{
public:
    Base(const CodeStuff::VersionStuff::Version & aVersion) : version_(aVersion)
    {
    }

    const CodeStuff::VersionStuff::Version getVersion() const {return version_;}

private:
    const CodeStuff::VersionStuff::Version version_;
};


#define CHILD_VERSION {1, 0, 0, 25}

class Child : public Base
{
public:
    Child() : Base(CodeStuff::VersionStuff::Version{std::vector<CodeStuff::VersionStuff::VersionType>{CHILD_VERSION}}) {}
};



int main(int argc, const char * argv[]) {

    Child myChild();
}

我的问题是,虽然我喜欢像#define CHILD_VERSION {1, 0, 0, 25} 那样轻松查看版本,但构造函数调用非常丑陋:

 Child() : Base(CodeStuff::VersionStuff::Version{std::vector<CodeStuff::VersionStuff::VersionType>{CHILD_VERSION}}) {}

我想这样做:

Child() : Base(CHILD_VERSION) {}

但在 XCode 中,这会导致“No Matching Constructor for Initialization of Base”的错误。因为这是有效的语法:

std::vector<uint16_t> v({1, 0 ,0 ,25}); 

我不确定为什么短 Base(CHILD_VERSION) 在 c++11 中不起作用。

我怎样才能缩短这个?

【问题讨论】:

  • 为什么不使用具有 4 个值的结构?
  • @manni66 在完整版中,列表可以是任意长度并处理更广泛的功能。

标签: c++ class c++11 vector


【解决方案1】:

我最近处理了非常类似的事情,我没有传递向量,而是使用std::initializater_list 作为获取简单常量版本号的途径。这是一个例子:

class Version {
  std::vector<unsigned> version;
 public:
  Version(const std::string & s);
  Version(std::initializer_list<unsigned> list) : version(list) {}
  bool operator== (const Version & other) const {
    return version == other.version;
  }
  bool operator< (const Version & other) const {
    return version < other.version;
  }
};

这里可以这样创建一个版本:

Version v{1, 0 ,0 ,25};

您也可以让您的基类也有一个std::initializer_list 构造函数,并将它传递给您的version_ 对象。

【讨论】:

  • 为什么编译器不把我的初始化列表转换成正常的向量?我正在考虑使用它并将构造函数与已经使用向量的代码保持在一起。
  • @Steve 代码只允许执行一个隐式构造函数。允许您执行 {1, 2, 3, 4} 的向量构造函数是一个接受初始化列表的构造函数,但没有接受 4 个参数的向量构造函数。编译器不允许说“我希望这是一个向量,并且向量有一个与传递的参数匹配的初始化列表构造函数,所以我要将参数转换为初始化列表,然后再转换为向量” -事实上,从你所在的地方到你想去的地方需要 2 次跳跃。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-06
  • 1970-01-01
  • 1970-01-01
  • 2015-02-25
  • 1970-01-01
相关资源
最近更新 更多