对象字段返回对象本身,而不是存储在字段中的实例

An object field returns the object itself, not an instance stored in the field

本文关键字:对象 字段 存储 实例 返回      更新时间:2023-10-16

(不确定这个标题是否是最好的描述…)

大家好。我需要以下代码的帮助。在process函数中,我希望cccc_sub(作为cc中的字段获得)显示不同的内容(因为它们最初是这样做的),但它们显示相同的内容。在CCD_ 6函数中生成CCD_。有人能告诉我出了什么问题以及如何解决这个问题吗?非常感谢。

Int process(const Storage cc) {
    Storage cc_sub = (Storage&) cc.data;  // Here
    cout << ... << endl;         // Contents from cc and cc_sub are the same though they are not supposed to be.
}
class Storage {
    public:
        Storage() {
            this->data = NULL;
        }
        Storage(const Storage& obj) { //Copy Constructor. Result is the same even if I removed this entire clause.
            this->data = obj.data;
        }
        void* data;
        void setData(Storage dPtr) {
            this->data = &dPtr;
        }
};
Storage makeObj(std::string* s) { // I want to keep the return value as value instead of pointer, 
                       // since when it returns pointer the values pointed by reference behaved unexpectedly (guess it's because of temporary object type of error)... 
    Storage cc;
    :
    cc.setData(makeObj(&subString)); 
    return cc;
    :
}

您看到的奇怪行为是由于在setDatamakeObj中操纵临时Storage变量造成的。这种操作的结果在C++中是未定义的。

尝试以下操作:

void process(const Storage cc) {
    Storage cc_sub = *((Storage*)cc.data);
    cout << ... << endl;
}
class Storage {
    public:
        Storage() {
            this->data = NULL;
        }
        Storage(const Storage& obj) {
            this->data = obj.data;
        }
        void* data;
        void setData(Storage* dPtr) {
            this->data = dPtr;
        }
};
Storage* makeObj(std::string* s) {
    // Allocate memory on the heap so that cc lives beyond this function call
    Storage* cc = new Storage;
    :
    // Populate the sub-storage with a heap-allocated variable
    cc->setData(makeObj(&subString));
    return cc;
}

注意,当前编写的makeObj代码如果被调用,将导致堆栈溢出,因为它无法结束递归。。。

根据cHao的建议,这里有一个使用shared_ptr(Microsoft Visual Studio 2008版本-您可能需要根据编译器更改#include <memory>和/或std::tr1::shared_ptr)的更完整的程序。我已经将数据类型从void*更改为Storageshared_ptr),并添加了一个字符串成员以更好地显示差异:

#include <string>
#include <iostream>
#include <memory>
using namespace std;
using namespace std::tr1;
class Storage {
    public:
        Storage() {
        }
        Storage(const Storage& obj) {
            this->data = obj.data;
        }
    string s;
    shared_ptr<Storage> data;
        void setData(shared_ptr<Storage> dPtr) {
            this->data = dPtr;
        }
};
void process(const shared_ptr<Storage> cc) {
    shared_ptr<Storage> cc_sub = cc.get()->data;
    cout << "Parent string: " << cc.get()->s << endl << 
            "Child string: " << cc_sub.get()->s << endl;
    cout << "Parent data pointer: " << cc.get()->data << endl << 
            "Child data pointer: " << cc_sub.get()->data << endl;
}
shared_ptr<Storage> makeObj(string* s) {
    shared_ptr<Storage> cc(new Storage);
    if (s->length() != 0) {
        string subString = s->substr(0, s->length()-1);
        cc->s = subString;
        cc->setData(makeObj(&subString));
    }
    return cc;
}

int main(int argc, char* argv[]) {
    string s = "hello";
    shared_ptr<Storage> storage = makeObj(&s);
    process(storage);
    return 0;
}

在我开始之前:您想用(Storage &)铸件实现什么?我想我不知道语法。我会尽量使用我认为你在做什么的最接近的估计。

编辑:我的这部分回答已经过时了,请参阅下面的评论。

当你这样做时:

Storage cc_sub = *(Storage *) cc.data;

您正在获取指针cc.data,将其强制转换为Storage,然后将其分配给变量cc_sub。复制构造函数几乎没有什么作用用这个。尝试重写赋值运算符,看看是否帮助。或者试试:

Storage cc_sub(*(Storage*) cc.data);

以进行显式复制构造函数调用。

如果它仍然没有帮助,它可能与您的程序逻辑有关,正如我所看到的,您正在使用data成员递归引用Storage实例。。。(毕竟,如果你的cc.data指向cc,那么行为是正确的,不是吗?)