相关疑难解决方法(0)

main()真的是一个C++程序的开始吗?

C++标准中的$ 3.6.1/1节,

程序应包含一个名为main的全局函数,它是程序的指定开始.

现在考虑这段代码,

int square(int i) { return i*i; }
int user_main()
{ 
    for ( int i = 0 ; i < 10 ; ++i )
           std::cout << square(i) << endl;
    return 0;
}
int main_ret= user_main();
int main() 
{
        return main_ret;
}
Run Code Online (Sandbox Code Playgroud)

此示例代码执行我打算执行的操作,即进入main()应该是程序"开始" 的函数之前打印从0到9的整数平方.

我还用-pedantic选项GCC 4.5.0 编译它.它没有错误,甚至没有警告!

所以我的问题是,

这段代码真的符合标准吗?

如果它符合标准,那么它是否会使标准所说的无效?main()不是这个计划的开始!user_main()在执行之前执行main().

我知道要初始化全局变量main_ret,use_main()首先执行,但这是完全不同的事情; 关键是,它确实使标准中的引用语句$ 3.6.1/1无效,因为main() …

c++ program-entry-point standards-compliance entry-point

130
推荐指数
6
解决办法
2万
查看次数

为什么C++需要用户提供的默认构造函数来默认构造一个const对象?

C++标准(第8.5节)说:

如果程序要求对const限定类型T的对象进行默认初始化,则T应为具有用户提供的默认构造函数的类类型.

为什么?在这种情况下,我无法想到为什么需要用户提供的构造函数.

struct B{
  B():x(42){}
  int doSomeStuff() const{return x;}
  int x;
};

struct A{
  A(){}//other than "because the standard says so", why is this line required?

  B b;//not required for this example, just to illustrate
      //how this situation isn't totally useless
};

int main(){
  const A a;
}
Run Code Online (Sandbox Code Playgroud)

c++

96
推荐指数
3
解决办法
2万
查看次数

c ++数组初始化

可能重复:
如何在C
数组初始化中初始化数组,引用前一个元素ok?

我想知道在c/c ++标准中进行这样的初始化是否安全:

int a = 5;
int tab[] = { a , tab[0] + 1 , tab[1] };
Run Code Online (Sandbox Code Playgroud)

它成功编译并执行gcc 4.5和clang 2.9,但它总是真的吗?


打印此表给出5 6 6.它在全球范围内初始化.


通常它在c和c ++中都很有趣,但我想在c ++中使用它:)

c++ arrays initialization

16
推荐指数
3
解决办法
3268
查看次数

为什么C++原始类型没有像其他类型那样初始化?

我知道,在C++中,当你写作时

int i;
Run Code Online (Sandbox Code Playgroud)

在有效地为其赋值之前,您不能对变量将保持的值做任何假设.但是,如果你写

int i = int();
Run Code Online (Sandbox Code Playgroud)

那么你有保证i0.所以我的问题是,它实际上并不是语言行为的一种不完整性吗?我的意思是,如果我已经定义了一个类MyClass并且写了

MyClass myInstance;
Run Code Online (Sandbox Code Playgroud)

我可以放心,没有类参数的默认构造函数将被调用以初始化myInstance(如果没有,编译器将失败),因为这就是RAII原理的方式.但是,当涉及到原始类型时,资源获取似乎不再是初始化.这是为什么?

我不认为改变从C继承的这种行为会破坏任何现有的代码(世界上是否有任何代码假设不能对变量的值做出假设?),所以主要可能的原因我想到的就是性能,例如在创建基本类型的大数组时; 但是,我还想知道是否有一些官方解释.

谢谢.

c++ primitive constructor raii

10
推荐指数
2
解决办法
3077
查看次数

与显式初始化相比,了解C++中的复制初始化

为什么第一个注释行正确编译,而第二个没有?

为什么可以a将自己作为构造函数参数,但b不能?
这两个人做的不一样吗?

class Foo { Foo &operator =(Foo const &); /* Disable assignment */ };

int main()
{
    Foo a = a;  // OK
    Foo  b(b);  // error C2065: 'b' : undeclared identifier
}
Run Code Online (Sandbox Code Playgroud)

更新

由于它看起来像编译器依赖,似乎问题比我想象的更严重.
所以我想问题的另一部分是,以下代码是否有效?

它在GCC中出错,但Visual C++执行得很好.

int main()
{
    int i = 0;
    { int *i(&i); }
    return i;
}
Run Code Online (Sandbox Code Playgroud)

c++ constructor initialization

8
推荐指数
1
解决办法
217
查看次数

为什么我可以在一个文件中按顺序初始化两个静态类变量而不是三个?

我正在使用静态类变量,我碰到了一些我不明白的意外情况.

Stroustrup的书TC++ PL4在15.4.1非局部变量的初始化中说,"在不同的翻译单元中没有保证全局变量初始化的顺序." 但是看到多个翻译单元; 我没有测试文件之间的依赖关系,这是在一个文件中.同一部分说"原则上,在main()调用之前初始化在任何函数外部定义的变量(即全局,名称空间和类静态变量).翻译单元中的这些非局部变量按其定义顺序初始化.

如果我在文件的顶部设置它:

class Test1 {
public:
static double test1;
};

class Test2 {
public:
static double test2;
};

class Test3 {
public:
static double test3;
};
Run Code Online (Sandbox Code Playgroud)

我可以做这个:

double Test2::test2 = Test1::test1;
double Test1::test1 = 1.125;
Run Code Online (Sandbox Code Playgroud)

并将此语句放在main中以检查值:

cout << Test1::test1 << " " << Test2::test2;
Run Code Online (Sandbox Code Playgroud)

两个值都是1.125.我知道这两个变量都在这个范围内定义,但是如果它们按定义顺序初始化,那么上面的语句如何使用下面语句中的数据呢?此外,顶部的类定义顺序在任何这些情况下都不会改变.

如果我使用这种安排:

double Test2::test2 = Test1::test1;
double Test3::test3 = Test2::test2;
double Test1::test1 = 1.125;
Run Code Online (Sandbox Code Playgroud)

它们也都是1.125.

但如果我这样做:

double Test3::test3 = Test2::test2;
double Test2::test2 = Test1::test1;
double Test1::test1 = 1.125;
Run Code Online (Sandbox Code Playgroud)

Test3::test3 将是0. …

c++

8
推荐指数
1
解决办法
130
查看次数

静态和动态初始化仅适用于非局部变量吗?

这是代码:

int factorial(int n)
{
     if ( n < 0 )       return -1; //indicates input error
     else if ( n == 0 ) return 1;
     else               return n * factorial(n-1);
}

int const a = 10 ; //static initialization 
             //10 is known at compile time. Its 10!

int const b = factorial(8); //dynamic initialization 
                      //factorial(8) isn't known at compile time,
                      //rather it's computed at runtime.
Run Code Online (Sandbox Code Playgroud)

(从这里被盗)

因此,对我来说,为什么b动态初始化并a静态初始化是有道理的.

但是,如果a并且b具有自动存储持续时间(可能已经初始化main()),那么您是否仍可以将其初始化称为静态或动态?因为对我来说,它们听起来像初始化的一般名称,而不是复制初始化. …

c++

5
推荐指数
1
解决办法
435
查看次数

线程局部变量的初始化

我最近使用了一个对象,其目的是将内存作为单例进行分配和释放。就像是

class MyValue
{
  // ...

  static Allocator& GetAllocator()
  {
    static Allocator allocator;
    return allocator;
  }

  // ...
};
Run Code Online (Sandbox Code Playgroud)

后来我意识到它Allocator不是线程安全的:当多个线程同时使用同一个分配器时,偶尔会发生奇怪的事情,导致断言和分段错误。

解决方案:为不同的线程使用不同的分配器:

class MyValue
{
  // ...

  static Allocator& GetAllocator()
  {
    thread_local static Allocator allocator;
    return allocator;
  }

  // ...
};
Run Code Online (Sandbox Code Playgroud)

惊人的!我的问题都消失了!只有一个问题: 每次创建线程时我的分配器变量都会被初始化,即使大多数线程不会使用该变量?

分配器的初始化可能是繁重的操作,因此我希望仅在实际需要时才对其进行初始化,而不是在每个线程中进行初始化。

我读到thread_local变量是由每个线程分配的。这是否意味着它们也是被构建的?这种分配(或构造)是针对创建的每个线程系统地发生还是仅针对使用它的线程发生?

我依稀记得在课程中听说过有关线程和线程本地存储的大多数细节都依赖于平台。如果是这样的话,我对 Linux 和 FreeBSD 特别感兴趣。


相关(有趣的读物,但我在那里找不到答案):

c++ multithreading thread-local-storage c++11

3
推荐指数
1
解决办法
6023
查看次数

子类不继承祖父项属性

我有以下C++代码:

#include <iostream>
#include <string>
using namespace std;

class Surface
{
public:
    virtual void draw();
protected:
    int x,y;
};

class Control: public Surface
{
public:
    Control(): x(10), y(10), name("control") { cout << "Control constructor" << endl; }
    void draw() {}
protected:
    string name;
};

class Label: public Control
{
public:
    Label(): x(10), y(10), name("label"), text("label") { cout << "Label constructor" << endl; }
    void draw() { cout << "drawing a label" << endl; }

protected:
    string text;
};

int main(int …
Run Code Online (Sandbox Code Playgroud)

c++

2
推荐指数
1
解决办法
1978
查看次数