【问题标题】:C++: How does it work alias members class?C++:别名成员类是如何工作的?
【发布时间】:2014-10-03 21:35:05
【问题描述】:

在以下代码中:

class prova: public std::map< int,int >
{
 public:
 prova():a(5){}
 int a;

};

int main()
{
 std::vector<prova> p;
 prova obj;
 p.push_back(obj); 
 return 0;
}

它可以正常工作; 如果我添加参考成员

class prova: public std::map< int,int >
{
 public:
 prova():a(5){}
 int a;
 int& b=a;
};

int main()
{
 std::vector<prova> p;
 prova obj;
 p.push_back(obj); 
 return 0;
}

我有

warning: non-static data member initializers only     available with -std=c++11 or -std=gnu++11 [enabled by default]|
/home/andrea/Scaricati/prova.cpp||In instantiation of ‘void 
std::vector<_Tp,_Alloc>::_M_insert_aux(std::vector<_Tp, _Alloc>::iterator, const _Tp&) 
[with _Tp = prova; _Alloc = std::allocator<prova>; 
std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<prova*, std::vector<prova> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = prova*]’:|
/usr/include/c++/4.8/bits/stl_vector.h|913|required from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = prova; _Alloc = std::allocator<prova>;   std::vector<_Tp, _Alloc>::value_type = prova]’|
/home/andrea/Scaricati/prova.cpp|19|required from here|
/home/andrea/Scaricati/prova.cpp|4|error: non-static reference member ‘int& prova::b’,     can’t use default assignment operator|
/usr/include/c++/4.8/bits/vector.tcc|335|note: synthesized method ‘prova&     prova::operator=(const prova&)’ first required here     
|||=== Build failed: 1 error(s), 4 warning(s) (0 minute(s), 0 second(s)) ===|

像警告中建议的那样添加 -std=g++11 没有问题。 如果我删除向量声明,我只会收到没有错误的警告。 为什么 C++ 旧标准做不到?引用属性有什么问题?是否有一个系统可以在不使用 c++11 标准的情况下做同样的事情?我试试

class prova: public std::map< int,int >
{
 public:
 prova():a(5),b(a){}
 int a;
 int &b;
};

但我得到了错误。为什么这个?谢谢!

【问题讨论】:

  • 非静态数据成员初始化器是 C++11 的一个特性。无论如何,如果您维护自引用,则需要自己编写复制 ctor 和赋值运算符,否则事情会变得一团糟。
  • “为什么 C++ 旧标准不能做到这一点?”:如警告中所述,“非静态数据成员初始化器仅适用于 -std=c++11 或 -std=gnu+ +11”。老实说,我不确定为什么这不是错误 - 我不知道 C++11 之前模式下的编译器对非静态成员初始化器做了什么。
  • 好的..但是为什么迭代器出错了?!
  • @volperossa:因为来自左值的push_back() 需要复制元素并作为错误状态(当然 - 它被埋在一堆噪音中;这仍然是 C++ 模板错误的一个大问题): “错误:非静态引用成员'int&amp; prova::b',不能使用默认赋值运算符”。所以,作为 T.C.提到,您需要定义自己的复制操作才能正确处理引用。

标签: c++ class c++11 reference alias


【解决方案1】:

您会收到警告,因为您的编译器足够聪明,可以了解 C++11 的语法。在 C++ 中,这种语法 int&amp; b= a 称为 类内成员初始化器,而在以前的标准中,这只能使用 static const 变量来完成。 C++11 放宽了这些限制。

来自Stroustrup's page:

在 C++98 中,只有 static const 整数类型的成员可以 在类中初始化,并且初始化器必须是常量 表达。这些限制确保我们可以做到 在编译时初始化。

例如:

int var = 7;

class X {       
    static const int m1 = 7;        // ok       
    const int m2 = 7;               // error: not static        
    static int m3 = 7;              // error: not const         
    static const int m4 = var;      // error: initializer not constant expression 
    static const string m5 = "odd"; // error: not integral type         
    // ...  
}; 

C++11 的基本思想是允许非静态数据成员 在声明它的地方初始化(在它的类中)。构造函数可以 然后在需要运行时初始化时使用初始化程序。 考虑:

class A {   
public: 
    int a = 7;  
};

这相当于:

class A {   
public:         
    int a;      
    A() : a(7) {}   
};

【讨论】:

  • 这两个 A 在 C++14 中并不严格等价。第一个是聚合;第二个不是。
  • 谢谢,我不知道。我在帖子中删除了任何提及 C++14 的内容。
  • 好的,但是使用这个类 prova: public std::map { public: prova():a(5),b(a){} int a;诠释 &b; };我得到错误
  • 错误:非静态引用成员'int& prova::b',不能使用默认赋值运算符|
  • @volperossa:不确定,可能是你的编译器。在 VS2013 中为我工作。 (我从 std::map 中删除了继承,但这没关系)
猜你喜欢
  • 1970-01-01
  • 2012-05-14
  • 2021-11-29
  • 2022-11-02
  • 2021-11-26
  • 1970-01-01
  • 2017-05-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多