Parashift很好地解释了初始化列表,但没有解释为什么在ctor体中赋值之前创建了额外的变量副本,但是在通过初始化列表分配时不会创建额外的副本.
我甚至遇到过使用++ i而不是i ++的建议,因为前者避免在赋值之前创建临时i.对于在监管机构中分配的POD,它是否相同?在赋值发生之前创建临时变量?
换句话说,为什么编译器需要创建变量的额外副本?为什么不能直接分配变量?
为什么?
在我的雇主,政策是我们在构造函数中使用初始化列表,因为它更有效.
但是,我正在开发一个有45个数据成员需要初始化的类.根据策略,这必须在构造函数的初始化列表中完成.
除了可读性之外,大型初始化列表的缺点是什么?
据我所知,在C++ 11之前,在构造函数初始化列表中初始化成员数组的唯一方法是执行以下操作:
MyClass::MyClass(int arg) : member(arg), memberArray() {
// anything else that needs to be done in the c'tor
}
Run Code Online (Sandbox Code Playgroud)
但是,我有几个人告诉我他们对这个方法不屑一顾,并且for在构造函数体的循环中零初始化它可能更安全/更可读.
我还没有C++ 11支持,所以我不能使用初始化列表,等等.有没有人听说过的任何指导方针不鼓励在构造函数初始化列表中初始化成员数组?
此外,测试表明没有,但是对于多维数组使用这种语法应该没有任何问题,对吗?(例如,这不是某些编译器由于某种原因而搞砸的标准的一部分......)
我并不是说这是一个主观问题 - 我只是想知道是否有充分的理由使用/不使用上述语法.
非常感谢任何帮助.
c++ arrays coding-style multidimensional-array initialization-list
我正在为POD,STL和Arrays等复合类型开发一台小型(漂亮)打印机.在这样做的同时,我也在摆弄初始化列表,并且遇到了以下声明
std::vector<double[3]> arr{ { 10, 11, 12 }, { 20, 21, 22 } };
Run Code Online (Sandbox Code Playgroud)
似乎VC2013和G ++ 4.8都不是很开心并发出一致的错误信息,无论哪种情况对我都没有帮助
对于VC++: error C3074: an array can only be initialized with an initialize-list
对于G ++ 4.8: error: array must be initialized with a brace-enclosed initialize
所以这里不能使用初始化列表,要么我的语法不正确?
在类似的方面,以下语法似乎是有效的
std::vector<std::array<int, 3>> arr{ { 10, 11, 12 }, { 20, 21, 22 } };
Run Code Online (Sandbox Code Playgroud)
我的初始化列表可能有什么问题?
std::array而不是C类型数组,但我只是在试验. 以下是否有效?
class myClass
{
private:
...
int m_nDataLength;
boost::shared_array<int> m_pData;
...
public:
myClass(): ..., m_nDataLength(10), m_pData(new int[m_nDataLength]), ...
{
}
}
Run Code Online (Sandbox Code Playgroud)
我是否正确地假设初始化将完全按照我在ctor中给出的顺序发生?如果没有,如果在m_pData之后m_nDataLength的初始化发生了怎么办?
c++ constructor memory-management smart-pointers initialization-list
在"C++ Primer"的第16章末尾,我遇到了以下代码(我删除了一堆行):
class Sales_item {
public:
// default constructor: unbound handle
Sales_item(): h() { }
private:
Handle<Item_base> h; // use-counted handle
};
Run Code Online (Sandbox Code Playgroud)
我的问题在于Sales_item(): h() { }线路.
为了完整起见,我还要引用我认为与我的问题相关的Handle类模板的部分(我想我不需要显示Item_base类):
template <class T> class Handle {
public:
// unbound handle
Handle(T *p = 0): ptr(p), use(new size_t(1)) { }
private:
T* ptr; // shared object
size_t *use; // count of how many Handles point to *ptr
};
Run Code Online (Sandbox Code Playgroud)
我原以为是这样的:
a)Sales_item(): h(0) { }这是作者在前几章中反复使用的惯例,或者
b)Handle<Item_base>()如果打算调用Handle类的默认构造函数.
相反,这本书有什么Sales_item(): h() { …
我开始使用Qt(和C++,在较小程度上),我想确保在继续之前完全理解基本代码.我知道初始化列表中的第一个元素用于选择非默认的继承构造函数.
但是ui(新的Ui :: TestAppMain)的目的是什么?在我看来它将是一个无限循环,因为ui被设置为构造函数中的TestAppMain的新实例,但事实并非如此.
namespace Ui {
class TestAppMain;
}
class TestAppMain : public QMainWindow{
public:
explicit TestAppMain(QWidget *parent = 0);
private:
Ui::TestAppMain *ui;
};
TestAppMain::TestAppMain(QWidget *parent): QMainWindow(parent), ui(new Ui::TestAppMain){
ui->setupUi(this);
}
Run Code Online (Sandbox Code Playgroud) 考虑这个构造函数: Packet() : bits_(0), datalen_(0), next_(0) {}
注意bits_,datalen_并且next_Packet类中的字段定义如下:
u_char* bits_;
u_int datalen_;
Packet* next_;
Run Code Online (Sandbox Code Playgroud)
这部分构造函数意味着什么? bits_(0), datalen_(0), next_(0)
有人能解释下面例子中用双花括号和单花括号初始化之间的行为差异吗?
代码#1:
vector<string> v = {"a", "b"};
string c(v[0] + v[1]);
cout << "c = " << c;
cout << "c.c_str() = " << c.c_str();
Run Code Online (Sandbox Code Playgroud)
输出#1:
c = ab
c.c_str() = ab
Run Code Online (Sandbox Code Playgroud)
代码#2:
vector<string> v = {{"a", "b"}};
string c(v[0] + v[1]);
cout << "c = " << c;
cout << "c.c_str() = " << c.c_str();
Run Code Online (Sandbox Code Playgroud)
输出#2:
c = a\acke?Z\
c.c_str() = a
Run Code Online (Sandbox Code Playgroud) 如何在构造函数初始化列表中启用ADL?例如,假设我有一个bignum具有命名空间级abs功能.现在我想编写一个类Foo,用传递给构造函数的实例的绝对值初始化其成员; 它应该使用命名空间级别,abs如果它存在,std::abs否则:
template<typename T>
struct Foo
{
T _data;
Foo(T data):
_data(abs(data)) // I want find abs with ADL here
{}
};
Run Code Online (Sandbox Code Playgroud)
无论如何,在类范围内禁止使用声明,我不想"污染"命名空间.如何启用ADL以使其在构造函数初始化列表中工作?