C++ 在头文件中分配新对象

C++ 在头文件中分配新对象,c++,C++,在调试空指针问题时,我在代码库中遇到了这种模式: #include <iostream> class Foo { public: Foo() {

在调试空指针问题时,我在代码库中遇到了这种模式:

#include <iostream>                                   

class Foo {                                           
  public:                                             
    Foo() {                                           
      std::cout << "In Foo constructor." << std::endl;
    };                                                
};                                                    

static const Foo* DEFAULT_FOO(new Foo);               
#包括
类Foo{
公众:
Foo(){

std::cout当编译单元
#include
是一个文件时,它基本上只是将标题中的文本插入到编译单元中。因此,在原始版本中,每个编译单元将包括以下行:

static const Foo* DEFAULT_FOO(new Foo);
因此,每个人将分配/构造一个
Foo
对象


将该行移到cpp文件中意味着实际上只有一个编译单元将创建该对象。

您的倒数第二段非常准确,并且很好地概括了这是一个坏主意的原因

你的最后一段,我不知道。由于指针值本身不是常量,它可能会被代码中的任何东西弄乱

你错过了一件事——对象也被泄漏了。虽然这不是什么大问题,因为它只需要在程序关闭时被删除,但是如果需要在析构函数中调用任何重要的东西,它将被跳过(除非有外部代码来删除指针,这甚至更混乱)


因此,您应该将其包装在智能指针中,或者只是将其作为常规对象而不是动态分配,或者检查singleton模式。

您的错误代码是正确的。首先,您不应该在头中声明静态变量-这没有意义,因为头包含在每个cpp文件中!所以最后是不同默认_FOO!的多个副本(因为每个cpp文件都将其视为静态,所以它正在创建自己的本地符号)。这就是为什么您看不到任何链接错误的原因


因此,在头文件中声明变量(使用extern),在cpp文件中定义它们,保持冷静并继续学习。

关于漏洞的精彩之处,我没有考虑到这一点。在原始代码中,它实际上是一个boost::shared\u ptr,但我认为Foo*会更清楚地说明这个问题。啊,经过考虑,我认为我应该将问题写成
静态Foo*const
,因为在我的源代码中是
const boost::shared_ptr
。@JamesBailey制作一个指向将在整个程序生命周期内存在的对象的共享指针更奇怪。我看不出需要从堆分配开始。为什么不简单地将const FOO DefaultFoo外部化呢?这样对象就具有
boost::shared_ptr
成员可以用
DEFAULT\u FOO
初始化。对象本身有FOO指针,而不是FOO值,以获得
FooImplA
FooImplB
@M.M的多态性。我不理解请求对不起,我假设所有的caps都表示这是一个宏定义的elseh,而我习惯性地按照惯例设置consts all capsC++中的约定只使宏全部都是上限吗?