我对value-&default-&zero-initialization非常困惑.特别是当他们参与不同的标准C++ 03和C++ 11(和C++ 14)时.
我引用并试图在这里扩展一个非常好的答案Value-/Default-/Zero-初始化C++ 98和C++ 03,以使其更加通用,因为它可以帮助很多用户,如果有人可以帮助填写需要差距,以便对何时发生的情况有一个很好的概述?
通过示例的全面见解简而言之:
有时新运算符返回的内存将被初始化,有时它不会取决于您正在新建的类型是POD(普通旧数据),还是它是一个包含POD成员且正在使用的类编译器生成的默认构造函数.
假设:
struct A { int m; };
struct B { ~B(); int m; };
struct C { C() : m(){}; ~C(); int m; };
struct D { D(){}; int m; };
struct E { …
Run Code Online (Sandbox Code Playgroud) 我在我的代码中声明了以下内容
vector <const A> mylist;
Run Code Online (Sandbox Code Playgroud)
我得到以下编译错误 -
new_allocator.h:75: error: `const _Tp* __gnu_cxx::new_allocator<_Tp>::address(const _Tp&) const \[with _Tp = const A]' and `_Tp* __gnu_cxx::new_allocator<_Tp>::address(_Tp&) const [with _Tp = const A]' cannot be overloaded
Run Code Online (Sandbox Code Playgroud)
但如果宣布 -
vector <A> mylist;
Run Code Online (Sandbox Code Playgroud)
我的代码编译.
在这种情况下不允许使用const吗?
我在这里复制我的代码供大家参考 -
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
A () {cout << "default constructor\n";}
A (int i): m(i) {cout << "non-default constructor\n";}
private:
int m;
};
int main (void)
{
vector<const A> mylist;
mylist.push_back(1);
return 0;
}
Run Code Online (Sandbox Code Playgroud) static
在C++中初始化数据成员的正确方法是什么?我也对它从C++ 98,C++ 11到C++ 14的变化感兴趣.
这是一个例子:
// bufferedOutput.h
class BufferedOutput
{
// Static member declaration.
static long bytecount;
};
// bufferedOutput.cpp
long BufferedOutput::bytecount = 50;
Run Code Online (Sandbox Code Playgroud)
还有其他方法来初始化static
数据成员吗?
使用此代码:
#include <iostream>
#include <list>
int main() {
std::cout << sizeof(std::list<void*>) << std::endl;
};
Run Code Online (Sandbox Code Playgroud)
我注意到在GCC 4.7 std::list<void*>
上,C++ 98 的大小是16字节,而它在C++ 11上的大小是24字节.
我想知道std :: list上有什么变化让它更大了.
我有一个函数,它接受一个数字并返回那么多东西(比方说,整数).什么是最干净的界面?一些想法:
vector<int>
.矢量将被复制多次,这是低效的.vector<int>*
.我的getter现在必须分配向量本身以及元素.有谁必须释放向量的所有常见问题,你不能分配一次并使用相同的存储器来进行对getter的许多不同调用等.这就是为什么STL算法通常避免分配内存,而是想要它传入了.unique_ptr<vector<int>>
.现在很清楚是谁删除了它,但我们还有其他问题.vector<int>
作为参考参数.getter可以push_back()
和调用者决定是否到reserve()
空间.但是,如果传入vector
非空,那么getter应该怎么做?附加?通过先清除它来覆盖?断言它是空的?如果函数的签名只允许一个解释,那将是很好的.begin
和end
迭代器.现在我们需要返回实际写入的项目数(可能小于预期),并且调用者需要注意不要访问从未写入的项目.iterator
,呼叫者可以通过insert_iterator
.char *
.:)所有学生都对 C++ using-directives的行为感到惊讶。考虑这个片段(Godbolt):
namespace NA {
int foo(Zoo::Lion);
}
namespace NB {
int foo(Zoo::Lion);
namespace NC {
namespace N1 {
int foo(Zoo::Cat);
}
namespace N2 {
int test() {
using namespace N1;
using namespace NA;
return foo(Zoo::Lion());
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
你可能认为test
会叫NA
的foo(Zoo::Lion)
; 但实际上它最终会调用N1
's foo(Zoo::Cat)
。
原因是这using namespace NA
实际上并没有将名称NA
带入当前范围;它带来他们到最小共同祖先的范围NA
和N2
,这是::
。并且using namespace N1
不会将名称N1
带入当前 …
以下代码段是我使用的记录器的简化版本.它扩展std::ostringstream
并可以使用<<
-operator 填充.销毁后,所有内容都会写入std::cout
.
将(<<
)直接写入临时对象,Logger()
我希望它能打印输入,但是,它只打印某些东西的地址std::cout
.写入临时对象的引用时Logger().stream()
,按预期工作.
为什么会这样?
顺便说一句,这种行为只发生在我必须使用的C++ 98-land(ideone)中.使用C++ 11(coliru)和C++ 14(ideone)时,两个调用变量都按预期工作.C++ 11/14有什么不同?
#include <iostream>
#include <sstream>
class Logger : public std::ostringstream
{
public:
~Logger()
{
std::cout << this->str() << std::endl;
}
Logger& stream()
{
return *this;
}
};
int main( int argc, char ** argv )
{
// 1.
// Prints an address, e.g. 0x106e89d5c.
Logger() << "foo";
// 2.
// Works as …
Run Code Online (Sandbox Code Playgroud) 我已经读过,在a的末尾添加项目的时间复杂度std::vector
是分摊的常量,并且在a的顶部和底部插入项目std::deque
是常量.因为这两个容器都具有随机访问迭代器,因此访问任何索引处的元素是不变的.如果我有任何这些事实错误,请告诉我.我的问题是如果访问a中的元素std::vector
或者std::deque
是不变的那么为什么通过擦除O(n)去除元素的时间复杂度.这里的答案之一说明通过擦除元素是O(n).我知道擦除会删除起始迭代器和结束迭代器之间的元素,所以答案基本上意味着它O(n)
取决于两个迭代器之间的元素的数量,并且从任何索引中的vector/deque中删除单个元素将为零?
注意:我们在这里谈论(据称)符合C++ 98的编译器.这不是C++ 11的问题.
我们在其中一个编译器中有一个奇怪的行为,我们不确定这是否正常或者这是否是编译器错误:
// This struct has a default constructor
struct AAA
{
AAA() : value(0) {}
int value ;
} ;
// This struct has a member of type AAA and an array of int, both surrounded
// by ints
struct BBB
{
int m_a ;
AAA m_b ;
int m_c ;
int m_d[42] ;
} ;
Run Code Online (Sandbox Code Playgroud)
当BBB初始化时:
BBB bbb = {0} ;
Run Code Online (Sandbox Code Playgroud)
我们期望BBB的所有POD成员(包括m_d,整数数组)被零初始化,并且要构建BBB的所有非POD成员.
这适用于AIX的本机编译器,在Linux/GCC-3.4上,在Windows/VisualC++上......但不适用于Solaris/SunStudio,其中只有非数组成员被零初始化.
我们在C++ 98标准(草案文档)中进行了一些研究,在那里我们发现了以下内容:
[12.6.1 - 2]
当聚合(无论是类还是数组)包含类类型的成员并由大括号括起的初始化列表(8.5.1)初始化时,每个这样的成员都由相应的赋值表达式进行复制初始化(见8.5).如果初始化列表中的初始值设定项少于聚合的成员,则未明确初始化的每个成员都应默认初始化(8.5).
然后:
[8.5 - 5]
对 …