Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.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++ 为什么可以';我不能分配这个指针吗?_C++_Pointers - Fatal编程技术网

C++ 为什么可以';我不能分配这个指针吗?

C++ 为什么可以';我不能分配这个指针吗?,c++,pointers,C++,Pointers,我有一个类ReferenceManager(一个处理书籍或期刊引用的类),其中包含以下数据成员: private: int arraySize; Reference **references; 这是“ReferenceManager”的主构造函数: Reference是我创建的另一个类 因此,据我所知,现在我们有一个指针Reference**references,它指向Reference*的指针数组。所有这些指针现在都指向NULL 到目前为止还不错 现在,考虑这个代码函数: R

我有一个类
ReferenceManager
(一个处理书籍或期刊引用的类),其中包含以下数据成员:

private:
    int arraySize;
    Reference **references;
这是“ReferenceManager”的主构造函数:

Reference
是我创建的另一个类

因此,据我所知,现在我们有一个指针
Reference**references
,它指向
Reference*
的指针数组。所有这些指针现在都指向
NULL

到目前为止还不错

现在,考虑这个代码函数:<代码> RealEngEngAs//Cuff>类:

bool ReferenceManager::insert(Reference &reference){
    for (int i = 0; i < arraySize; i++) {
        if((*(references) + i) == NULL){
            (*(references) + i) = &reference; //ERROR: expression not assignable
            cout << "Object placed in position " << i << "." << endl;
            return true;
        }
    }
    cout << "Array full!" << endl;
    return false;
}
bool ReferenceManager::insert(Reference&Reference){
for(int i=0;icout引用需要一个内存位置或左值。虽然*(引用)是一个左值,但当您将它添加到i时,它会变成一个在内存中没有位置的右值。这是您无法引用的内容。:

引用需要一个内存位置或左值。而*(引用)是一个左值,当您将它添加到i时,它将成为一个在内存中没有位置的右值。这是您无法引用的内容。

这是因为
(*(references)+i)
生成一个您无法分配的值。它相当于
(references[0]+i)

您可能想要
*(references+i)
references[i]
等效项。请选择后者。它们都返回左值引用-
reference*&

这是因为
(*(references)+i)
生成一个您无法分配的值。它等效于
(references[0]+i)

您可能需要
*(references+i)
references[i]
等效项。请选择后者。它们都返回左值引用-
reference*&
这是一个糟糕的开始:

ReferenceManager::ReferenceManager(int capacity):
arraySize(capacity)
{
    Reference* arrayOfreferencePointers[capacity];
    references = arrayOfreferencePointers;
}
您已在函数中声明了
ArrayOfReferencePoints
。这称为自动变量,当函数退出时它将被销毁。这将使类成员
引用
成为悬空指针,即不指向有效对象的指针

相反,您需要为数组使用动态分配。最好的方法是使用一个管理动态分配的类。您可以编写自己的类,但在标准库中已经有一个这样做的类,名为
std::vector
。您可以用
std::vector>替换
References**References;
参考资料;

所有这些指针现在都指向NULL

您从未初始化过它们中的任何一个,因此它们都是通配符。您需要使用初始值设定项将它们设置为null。但是,如果您遵循我的向量建议,则不需要这样做;增加向量会导致新项正确初始化。(指针的情况下默认为null指针)

insert
函数可以保持原样(括号如其他答案所示固定);但是它会导致代码更整洁,根据需要增加向量,而不是执行空指针搜索

注意:如果只实例化编译时已知大小的
ReferenceManager
,那么这将打开另一种方法:将
capacity
作为模板参数,并使用类成员数组而不是向量


就目前的设计而言,这不是一个好主意:

insert(Reference &reference)
原因是,按照惯例,接受引用的函数不应该存储对该对象的任何引用;它只应该在函数的持续时间访问对象。否则,您可能会再次生成悬空引用。例如,考虑此代码:

void func()
{
    Reference bob;
    manager->insert(bob);
    // oops...
}
现在,管理器将包含一个悬空引用,因为
bob
已被销毁,但bob的地址仍保留在管理器中。这将导致灾难

为了表明您可以存储对象,最好让insert函数接受指针。这是函数可以存储指针的自我文档。当然,有些人仍然可以编写:

Reference bob;
manager->insert(&bob);
但至少这更可能给阅读您的代码、熟悉我所描述的约定的人带来危险

传递
&bob
可能会存储地址;但是传递
bob
会存储一个副本


概括一下,重要的是要考虑您的ReferenceManager所指对象的生存期。您基本上有两个选择:

  • 经理还管理生命周期
  • 生命周期在其他地方进行管理,确保在管理器持有对对象的引用时永远不会销毁对象
第一种选择是让容器存储智能指针。

这是一个糟糕的开始:

ReferenceManager::ReferenceManager(int capacity):
arraySize(capacity)
{
    Reference* arrayOfreferencePointers[capacity];
    references = arrayOfreferencePointers;
}
您已在函数中声明了
ArrayOfReferencePoints
。这称为自动变量,当函数退出时它将被销毁。这将使类成员
引用
成为悬空指针,即不指向有效对象的指针

相反,您需要为数组使用动态分配。最好的方法是使用一个管理动态分配的类。您可以编写自己的类,但在标准库中已经有一个这样做的类,名为
std::vector
。您可以用
std::vector>替换
References**References;
参考资料;

所有这些指针现在都指向NULL

你从未初始化过它们中的任何一个,所以它们都是通配符。你需要使用初始值设定项将它们设置为null。但是如果你遵循我的vector sugge