我决定更熟悉我最喜欢的编程语言,但只读 阅读标准很无聊。
C ++中最令人惊讶,反直觉,或者只是简单的奇怪元素是什么?令你震惊的是你跑到最近的编译器检查它是否真的存在?
我会接受第一个答案,即使 我已经测试过它,我也不会相信。 :)
答案 0 :(得分:10)
我发现它有点令人惊讶
class aclass
{
public:
int a;
};
some_function(aclass());
将a
初始化为0
中的some_function
,而
aclass ac;
some_function(ac);
将保留单位资本。
如果明确定义aclass
的默认构造函数:
class aclass
{
public:
aclass(): a() {}
int a;
};
然后
aclass ac;
还会将a
初始化为0
。
答案 1 :(得分:9)
我可以添加的另一个答案是throw()
限定符。例如:
void dosomething() throw()
{
// ....
}
void doSomethingElse() throw(std::exception)
{
// ....
}
直观地说,这看起来像是与编译器的契约,表明除了列出的那些之外,不允许此函数抛出任何异常。但实际上,这在编译时没有任何作用。相反,它是一个运行时机制,它不会阻止该函数实际抛出异常。更糟糕的是,如果抛出未列出的异常,它会通过调用std::terminate()
来终止您的应用程序。
答案 2 :(得分:8)
几个声明者的顺序实际上是无序的:
volatile long int const long extern unsigned x;
与
相同extern const volatile unsigned long long int x;
答案 3 :(得分:5)
考虑到C ++通常是多么无情,我发现标准实际上允许你delete
空指针有点令人惊讶。
答案 4 :(得分:2)
对象在构造期间更改类型。
特别是,当从构造函数调用虚函数时,不将调用最派生的覆盖。而是从正在当前构建的类调用实现。如果该实现恰好是0
(纯虚函数),则程序将在运行时崩溃。
一个半现实世界的例子:
class AbstractBase {
public:
AbstractBase() {
log << "Creating " << className() << endl;
}
protected:
virtual string className() const = 0;
}
class ConcreteGuy {
protected:
virtual string className() const { return "ConcreteGuy"; }
}
构造ConcreteGuy
对象后,程序将以“调用纯虚函数”错误消息终止。
这就是为什么从构造函数调用虚函数被认为是邪恶的。
答案 5 :(得分:0)
众所周知,数组启动器可能像枚举定义一样跳转索引。
// initializing an array of int
int a[ 7] = { [5]=1, [2]=3, 2};
// resulting in
int a[ 7] = { 0, 0, 3, 2, 0, 1, 0};
// initializing an array of struct
struct { int x,y; } ar[ 4] = { [1].x=23, [3].y=34, [1].y=-1, [1].x=12};
// resulting in
struct { int x,y; } ar[ 4] = { { 0, 0}, { 12, -1}, { 0, 0}, { 0, 34}};
// interesting usage
char forbidden[ 256] = { ['a']=1, ['e']=1, ['i']=1, ['o']=1, ['u']=1};
大多数these也适用于C ++。
答案 6 :(得分:0)
在C ++语句中评估某事......
int main()
{
"This is a valid C++ program!"
"I will list the first five primes:";
2;
3;
5;
7;
11;
}