但是可以通过引用实现相同的功能吗?
MCanvasFont.h
namespace Impl {
class FontDelegate;
}
class MCanvasFont
{
public:
MCanvasFont();
virtual ~MCanvasFont();
protected:
// Reference count
long m_cRef;
// agg font delegate
const Impl::FontDelegate& m_font;
}
MCanvasFont.cpp
// helpers
#include "ImplHelpers/FontDelegate.h"
MCanvasFont::MCanvasFont()
: m_cRef(1),
m_font(Impl::FontDelegate() )
{
// constructor's body
}
附言这段代码在G++编译时没有任何问题。
最佳答案
您的程序中存在错误,并且在构造函数的初始化程序列表中:
MCanvasFont::MCanvasFont()
: m_cRef(1),
m_font(Impl::FontDelegate() ) // <--- BANG
{
Impl::FontDelegate()
的问题在于它构造了一个临时对象。这不会超过构造函数的寿命-实际上,它实际上是在进入构造函数主体之前被销毁的,因为它的生命周期就是它所出现的表达式的生命周期。因此,您的m_font
引用立即无效。尽管您可以使用手动分配的对象(
*new Impl::FontDelegate()
)对其进行初始化,但是如果分配失败,则您将处于未定义的区域,除非您在运行时启用了异常。无论如何,您仍然还必须在析构函数中对对象进行delete
。因此,引用实际上并不会给您带来任何好处,它只是使一些不自然的代码成为可能。我建议改用const指针:const Impl::FontDelegate* const m_font;
编辑:只是为了说明问题,请使用以下等效示例:
#include <iostream>
struct B
{
B() { std::cout << "B constructed\n"; }
~B() { std::cout << "B destroyed\n"; }
};
struct A
{
const B& b;
A() :
b(B())
{
std::cout << "A constructed\n";
}
void Foo()
{
std::cout << "A::Foo()\n";
}
~A()
{
std::cout << "A destroyed\n";
}
};
int main()
{
A a;
a.Foo();
}
如果运行此命令,输出将是:
B constructed
B destroyed
A constructed
A::Foo()
A destroyed
因此
b
几乎立即无效。