我所知道的使用初始化列表的好处是,它们在初始化非内置的类成员时提供效率。 例如, Fred::Fred() : x_(whatever) { } 优于, Fred::Fred() { x_ = whatever; } 如果x是自定义类的对象。 除此之外,为了保持一致性,甚至使用内置types也使用此样式。 这样做的最普遍的好处是提高了性能。 如果expression式与成员variablesx_的types相同,则expression式的结果直接在x_内部构造 – 编译器不会创build对象的单独副本。 使用其他样式,expression式会导致创build一个单独的临时对象,并将此临时对象传递给x_对象的赋值运算符。 然后那个临时对象被破坏了。 这是无效的。 题 在使用初始化列表的下面的例子中是否有任何效率增益。 我认为没有收获。 第一个版本调用string的复制构造函数,另一个调用string的赋值运算符(没有任何临时的创build)。 这是正确的? class MyClass { public: MyClass(string n):name(n) { } private: string name; }; class MyClass { public: MyClass(string n) { name=n; } private: string name; };
在C ++中,可以使用初始化程序列表在构造函数开始运行之前初始化类的字段。 例如: Foo::Foo(string s, double d, int n) : name(s), weight(d), age(n) { // Empty; already handled! } 我很好奇为什么Java没有类似的function。 根据核心Java:第1卷 : C ++使用这个特殊的语法来调用字段构造函数。 在Java中,不需要它,因为对象没有子对象,只有指向其他对象的指针。 这是我的问题: 他们是什么意思,“因为物体没有子物体?” 我不明白一个子对象是什么(我试图查找它); 它们是指一个扩展超类的子类的实例吗? 至于为什么Java没有像C ++这样的初始化器列表,我会假定原因是因为所有的字段在Java中已经被默认初始化了,而且因为Java使用super关键字来调用super(或者C ++术语中的base)-class构造函数。 它是否正确?
为什么不是std::initializer_list是内置的核心语言? 在我看来,这是C ++ 11的一个非常重要的特性,但它没有自己的保留关键字(或类似的东西)。 相反, initializer_list 只是标准库中的一个模板类,它具有来自编译器处理的新的braced-init-list {…}语法的特殊隐式映射 。 起初以为,这个解决scheme是相当黑客 。 这就是现在实现C ++语言的新增function:通过某些模板类的隐式angular色而不是核心语言? 请考虑这些例子: widget<int> w = {1,2,3}; //this is how we want to use a class 为什么select了一个新class级: widget( std::initializer_list<T> init ) 而不是使用类似于任何这些想法的东西: widget( T[] init, int length ) // (1) widget( T… init ) // (2) widget( std::vector<T> init ) // (3) 一个经典的数组,你可以在这里和那里添加const 语言中已经存在三个点(var-args,现在是可变参数模板),为什么不重用语法(并使之感觉内置 […]
我正在加快C ++ 0x的速度,并用g ++ 4.6进行testing 我只是尝试下面的代码,认为它会工作,但它不会编译。 我得到的错误: incompatible types in assignment of 'std::initializer_list<const int>' to 'const int [2]' struct Foo { int const data[2]; Foo(std::initializer_list<int const>& ini) : data(ini) {} }; Foo f = {1,3};
我有一个python类,看起来像这样: class Process: def __init__(self, PID, PPID, cmd, FDs, reachable, user): 其次是: self.PID=PID self.PPID=PPID self.cmd=cmd … 有没有办法自动初始化这些实例variables,如C ++的初始化列表? 它会腾出大量的冗余代码。
考虑下面的代码: int main() { int count = 0 ; int arrInt[2] = { count++, count++ } ; return 0 ; } 如果我们使用clang -std=c++03编译代码,则会产生以下警告( 现场示例 ): warning: multiple unsequenced modifications to 'count' [-Wunsequenced] int arrInt[2] = { count++, count++ } ; ^ ~~ 我不提倡这样的代码,但是类似的代码出现在另一个问题上,并且根据标准的C ++ 11是否定义了代码 。 在C ++ 11中,此行为是根据初始化程序列表中的多个突变未定义的行为定义的行为 ,实际上,如果使用-std=c++11则警告消失。 如果我们看一个预先的C ++ 11 草案标准,它不具有相同的语言覆盖初始化列表,所以看起来我们留下了Chapter 5 […]
我喜欢在C + + 11 auto 。 太棒了 但是它有一个矛盾让我很紧张,因为我一直在绊倒它: int i = 3; // i is an int with value 3 int i = int{3}; // i is an int with value 3 int i(3); // i is an int with value 3 (possibly narrowing, not in this case) int i{3}; // i is an int […]
是否有可能使用子类的构造函数的初始化列表初始化在父类中声明为受保护的数据成员? 我无法得到它的工作。 我可以解决这个问题,但是如果我不需要的话,那将会很好。 一些示例代码: class Parent { protected: std::string something; }; class Child : public Parent { private: Child() : something("Hello, World!") { } }; 当我尝试这样做时,编译器告诉我:“class'Child'没有任何名称为”something“的字段。 是这样的可能吗? 如果是这样,语法是什么? 非常感谢!
考虑一下function: template<typename T> void printme(T&& t) { for (auto i : t) std::cout << i; } 或任何其他函数期望与一个begin()/ end()启用types的一个参数。 为什么以下是非法的? printme({'a', 'b', 'c'}); 当所有这些都是合法的: printme(std::vector<char>({'a', 'b', 'c'})); printme(std::string("abc")); printme(std::array<char, 3> {'a', 'b', 'c'}); 我们甚至可以这样写: const auto il = {'a', 'b', 'c'}; printme(il); 要么 printme<std::initializer_list<char>>({'a', 'b', 'c'});
这个冒号运算符(“:”)在这个构造函数中做什么? 它相当于MyClass(m_classID = -1, m_userdata = 0); ? class MyClass { public: MyClass() : m_classID(-1), m_userdata(0) { } int m_classID; void *m_userdata; };