用指针初始化引用:有什么陷阱吗?还有其他选择吗?(C+;+;) P>因为绝望时代需要一些古怪的措施,我在C++中实现了以下的内容:
--有一个叫做foo的类。我需要一个名为bar的类中的foo实例(对象或引用,而不是指针)。用指针初始化引用:有什么陷阱吗?还有其他选择吗?(C+;+;) P>因为绝望时代需要一些古怪的措施,我在C++中实现了以下的内容:,c++,pointers,reference,C++,Pointers,Reference,--有一个叫做foo的类。我需要一个名为bar的类中的foo实例(对象或引用,而不是指针)。 --我不想在bar.h中将foo声明为对象,因为我不想在bar.h中包含foo.h。原因是bar.h包含在项目中大约一百个.cpp文件中,而将foo.h包含在bar.h中会大大增加编译时间并带来意大利面。 --我不想将forward foo分类并将其声明为指针,因为我们试图避免像瘟疫这样的指针。 --bar的构造函数不通过参数传递foo的实例 所以我这样做了: 这是foo.h(foo.cpp有很多数学知
--我不想在bar.h中将foo声明为对象,因为我不想在bar.h中包含foo.h。原因是bar.h包含在项目中大约一百个.cpp文件中,而将foo.h包含在bar.h中会大大增加编译时间并带来意大利面。
--我不想将forward foo分类并将其声明为指针,因为我们试图避免像瘟疫这样的指针。
--bar的构造函数不通过参数传递foo的实例 所以我这样做了: 这是foo.h(foo.cpp有很多数学知识,但在这个参数中并不重要): 这是bar.h:
#ifndef BAR_H
#define BAR_H
class bell;
class foo;
class bar {
public:
bar(const bell& bell_i);
virtual ~bar();
double bar_member(); /* does math in bar.cpp and uses foo */
private:
foo& myfoo;
};
#endif /* BAR_H */
这是bar.cpp:
#include "bell.h"
#include "foo.h"
bar::bar(const bell& bell_i) : myfoo(*(new foo(bell_i))) /* NOTE: this construction is my question. */
{}
bar::~bar()
{}
double bar::bar_member()
{
return sqrt(myfoo.foo_member());
}
因此,本质上,我创建了一个指向foo的指针,从中获取对象并初始化myfoo。这段代码和所有相关的代码都可以完美地编译,并且运行时没有任何错误。我已经用多个编译器对它进行了测试
我的问题是:
--在初始化myfoo时,在代码方面(语法/生命周期/悬空指针等)是否存在任何错误?--这样做在代码学上有什么错误吗?
--我错过什么了吗?
--有没有不使用指针的替代方案 如果你想看到真正的代码,它在这里: 提前谢谢。我是物理学家。所以,请原谅我的代码行话
更新:泄漏似乎不是一个问题,因为只有少数类实例是在初始化时构造的,在运行时没有销毁,只有在退出时销毁。但是,对于在运行时创建和销毁的类,不应该这样做。您的度量与这里的目的不符。现在,当您为foo实例分配内存时,会出现内存泄漏,而不是指针,但您永远不会释放它。如果您需要使用指针/引用,但不想手动跟踪对象生存期,则最好使用RAII方法,例如。它将握住您的对象指针,并在时机成熟时小心地将其释放。您的度量与此处的目的背道而驰。现在,当您为foo实例分配内存时,会出现内存泄漏,而不是指针,但您永远不会释放它。如果您需要使用指针/引用,但不想手动跟踪对象生存期,则最好使用RAII方法,例如。它将保存您的对象指针,并在时机成熟时小心地释放它。使用指针作为成员,但有一个返回引用的访问器
Foo&GetFoo(){return*pmyFoo;}
。使成员私有,并在任何地方使用访问器,即使在类的代码中也是如此
除了那一个方法(哦,还有释放它的dtor),就您的所有代码而言,没有指针,只有引用。使用指针作为成员,但是有一个访问器
Foo&GetFoo(){return*pmyFoo;}
返回引用。使成员私有,并在任何地方使用访问器,即使在类的代码中也是如此
除了那一个方法(哦,还有释放它的dtor),就您的所有代码而言,没有指针,只有引用。您的代码存在内存泄漏。这并不是真正回答您的问题,但为什么要避免像瘟疫这样的指针?他们一点也不坏。也许您正在考虑实际拥有对象的原始指针。你应该像瘟疫一样避免,但对于其他的,指针是非常好的implementation@talismanbrandi显然是这样。“你看起来不对劲,”护身符布兰迪说,“你在自欺欺人。”。你的代码有内存泄漏。结束。您的代码有内存泄漏。并没有真正回答您的问题,但为什么要避免像瘟疫这样的指针?他们一点也不坏。也许您正在考虑实际拥有对象的原始指针。你应该像瘟疫一样避免,但对于其他的,指针是非常好的implementation@talismanbrandi显然是这样。“你看起来不对劲,”护身符布兰迪说,“你在自欺欺人。”。你的代码有内存泄漏。例如,请检查以下代码:如果您运行它,您可以看到在堆栈(编号1)上创建的foo实例被构造,然后被销毁。实例2与您的代码中创建的相同,它永远不会被销毁。@talismanbrandi值得一提的是,如果您想手动处理内存管理(通常是一个坏主意),删除析构函数中的对象不足以解决问题。您还必须处理复制构造函数和复制赋值,如果使用C++11或更高版本,还必须处理移动构造函数和移动赋值。这在C++11中通常称为或。谢谢@FabioTurati。我们正在尽量减少手动内存管理。@talismanbrandi例如,请检查以下代码:如果您运行它,您可以看到在堆栈(编号1)上创建的foo实例被构造,然后被销毁。实例2与您的代码中创建的相同,它永远不会被销毁。@talismanbrandi值得一提的是,如果您想手动处理内存管理(通常是一个坏主意),删除析构函数中的对象不足以解决问题。您还必须处理复制构造函数和复制赋值,如果使用C++11或更高版本,还必须处理移动构造函数和移动赋值。这在C++11中通常称为或。谢谢@FabioTurati。我们正在努力减少手动内存管理。
#include "bell.h"
#include "foo.h"
bar::bar(const bell& bell_i) : myfoo(*(new foo(bell_i))) /* NOTE: this construction is my question. */
{}
bar::~bar()
{}
double bar::bar_member()
{
return sqrt(myfoo.foo_member());
}