Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用指针初始化引用:有什么陷阱吗?还有其他选择吗?(C+;+;) P>因为绝望时代需要一些古怪的措施,我在C++中实现了以下的内容:_C++_Pointers_Reference - Fatal编程技术网

用指针初始化引用:有什么陷阱吗?还有其他选择吗?(C+;+;) P>因为绝望时代需要一些古怪的措施,我在C++中实现了以下的内容:

用指针初始化引用:有什么陷阱吗?还有其他选择吗?(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有很多数学知

--有一个叫做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:

#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());
}