我有两个类,其中一个是基类,包含指向派生类上的成员对象的指针.
像这样:
class Bar { };
class Foo : Bar { };
class A
{
    public:
         A(Foo *foo) { this->foo = foo };
    private:
        Foo *foo;
}
class B : public A
{
    public:
        B() : A(&bar) { };
    private:
        Bar bar;
}
我的问题是:B.bar 保证在作为初始化参数传递给构造函数之前被分配A?
换句话说:如果我创建的一个实例B是B->foo保证是一个有效的指针的一个实例Bar?
使用{}而不是()在构造函数中允许我在头文件中使用特定构造函数初始化类成员,如下所示:
class X {
    private:
        std::vector y{1, 2, 3};
};
但是,我如何知道对于Z我使用的类Z z{a, b};将调用具有两个参数的构造函数Z::Z(int a, int b)- 而不是具有std::initializer_list?的那个?
我的意思是std::complex(1, 2)和std::complex{1, 2}是相同的,但std::vector(3)与std::vector{3}肯定不是.
除非我需要,我是否应该总是使用{}变体或使用?(){}
在成员资格测试频繁的算法中,我真的很想念infix∈运算符,我喜欢使用%运算符.它适用于常规容器,但由于某种原因clang和gcc拒绝初始化列表.毫无疑问,他们是"正确的",因为标准肯定会拒绝这一点.但为什么?
#include <initializer_list>
#include <iostream>
#include <vector>
/// Whether e ? m.
template <typename T, typename U>
inline bool
in(const U& k, const std::initializer_list<T>& m)
{
  return std::find(begin(m), end(m), k) != std::end(m);
}
/// Whether e ? m.
template <typename T, typename U>
inline bool
operator%(const U& k, const std::initializer_list<T>& m)
{
  return in(k, m);
}
/// Whether e ? m.
template <typename T, typename U>
inline bool
operator%(const U& k, const std::vector<T>& m)
{
  return in(k, m);
}
int …比方说,我有一个结构
struct A {
  A(int n) : n(n) {}
  int n;
};
我想std::vector用一些元素初始化一个.我可以通过使用初始化列表或通过安排新元素来完成此操作:
// 1st version: 3 ctors, 3 copy ctors, 3 dtors                                           
std::vector<A> v1{1, 2, 3};
// 2nd version: 3 ctors                                                                  
std::vector<A> v2;
v2.reserve(3);
v2.emplace_back(4);
v2.emplace_back(5);
v2.emplace_back(6);
正如评论所示,第一个版本调用3个构造函数,3个复制构造函数和3个析构函数.带有emplace的版本仅使用3个构造函数.
问题:显然第二个版本更好,但第一个版本更简洁.我可以两全其美吗?我可以直接初始化而无需额外费用吗?
(这里有一个更长的版本中的A显示发生了什么结构.)
在如何将初始化列表作为函数参数传递的答案中?,我看到了表达式:
return WaitForMultipleObjects(
    handles.size(), &*handles.begin(), wait_all, time
);
有什么意义&*呢?没有它,电话会有相同的含义吗?
另一个C++问题,我试图弄清楚在构造对象时使用"="会产生什么影响.考虑:
class Foo {
    private:
        int bar;
        int baz;
    public:
        Foo(int bar, int baz)
            :bar(bar), baz(baz) {}
};
int main() {
    Foo foo1{4, 2};
    Foo foo2 = {4, 2};
    Foo foo3 = Foo{4, 2}; // I prefer this one for aesthetic reasons.
    return 0;
}
有什么区别,我应该坚持哪种最佳做法?
此外,虽然我们讨论的是最佳实践的主题,但我听说添加explicit构造函数是一个好主意™因为隐式转换的奇怪行为.所以我添加explicit到构造函数Foo:
    public:
        explicit Foo(int bar, int baz)
            :bar(bar), baz(baz) {}
突然,这个:
    Foo foo2 = {4, 2};
无法编译错误:
error: chosen constructor is explicit in copy-initialization
这是为什么?
在下面的C++代码中,什么是类型a?typeid回报St16initializer_listIPKcE
auto a = { "lol", "life" };
在他的"使用C++编程,原理和实践"一书中,Bjarne Stroustrup 在第314-316页(第9.4.4节)中介绍了成员初始化列表的概念.他使用以下示例:
// Simple Date (year, month, day)
class Date
{
public:
    Date(int yy, int mm, int dd): y{yy}, m{mm}, d{dd}
    {
        //...
    }
private:
    int y, m, d;
};
在页315上他说:
我们本来可以写的:
Run Code Online (Sandbox Code Playgroud)Date::Date(int yy, int mm, int dd) // constructor { y = yy; m = mm; d = dd; }但是我们原则上首先会默认初始化成员,然后为它们分配值.
因此,我可以得出结论,使用成员初始化列表使代码稍快一些吗?当然,没有人会注意到现代PC.但我打算使用C++进行嵌入式开发.
编辑:
我将进一步说明我的问题.通过"稍微快一点",我实际上意味着"更少的CPU周期".
我也同意这个特定例子的潜在效率提升几乎为零.但是对于更大的类和结构,它可能在微控制器上变得明显.
可以通过多种方式来初始化C ++中的对象(类或结构的实例)。某些语法引起对象的直接初始化,而其他语法则导致复制初始化。随着拷贝省音在编译器中启用,两者具有相同的性能。在禁用复制删除的情况下,当您为每个实例选择复制/初始化时,都会有一个附加的复制/移动构造函数调用(复制初始化)。
结论:复制初始化可能会降低性能!
来自以下问题:C ++ 11成员初始值设定项列表与类初始值设定项?我可以得出结论,这将是复制初始化语法:
obj s = obj("value");
这将是直接初始化语法:
obj s{"value"};
 
但是这个呢?
obj s = {"value"};
还有这个:
obj s = obj{"value"};
还有这个:
obj s("value");
或者这个:
obj s = "value";
注意
 
Bjarne Stroustrup在他的书“使用C ++编程,原理和实践”第二版,第311页,第9.4.2节中比较了一些初始化样式(但不是全部):
Run Code Online (Sandbox Code Playgroud)struct Date { int y,m,d; //year, month, day Date(int y, int m, int d); //check for valid date and initialize void add_day(int n); //increase the Date by n days };... …
我正在用C++实现一个Matrix类,我希望能够用一个初始化列表来初始化它,如下所示:
Matrix<double, 2, 3> m({{1,2,1}, 
                        {0,1,1}});
在类中我实现了这样的构造函数:
template<typename Ty, unsigned int rows, unsigned int cols>
class Matrix
{
    std::array<std::array<Ty, cols>, rows> data;
public:
    Matrix(const std::initializer_list<std::initializer_list<Ty>>& list)
    {
        int i = 0;
        for (auto& list_row : list)
        {
            int j = 0;
            for (auto& list_value : list_row)
            {
                data[i][j++] = list_value;
            }
            i++;
        }
    }
}
代码工作,但我有几个问题.是否可以使它安全,所以它只需要一定大小的初始化列表(矩阵的大小),其次我可以使代码更简洁 - 我曾想象过这样的事情:
Matrix(const std::initializer_list<std::initializer_list<Ty>>& list)
    : data(list)
{ }
它不起作用,但任何更好的方法,将不胜感激.
c++ ×10
initializer-list ×10
c++11 ×8
auto ×1
c++14 ×1
constructor ×1
inheritance ×1
stdarray ×1
stl ×1
types ×1