【发布时间】:2018-10-29 11:00:34
【问题描述】:
我有这样的程序:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
class no_object : public std::exception
{
protected:
std::string mMsg;
public:
no_object(const char* msg) : mMsg(msg) {}
virtual ~no_object() noexcept override {}
virtual const char* what() const noexcept override { return mMsg.c_str(); }
};
using namespace std;
class Object {
public:
Object(const string info) : information(info) { cout << "Object constructor!" << endl; }
~Object() { cout << "Object destructor!" << endl; }
Object(const Object& obj) { information = obj.information; cout << "Copy constructor!" << endl; }
void setInformation() { }
string getInformation() const { return information; }
private:
string information;
};
class Storage {
public:
Storage(const size_t width) {
objs = static_cast<Object*>(malloc(sizeof(Object) * width));
if (objs == NULL)
throw std::bad_alloc();
lastPointer = objs + sizeof (Object) * (width - 1);
}
void storeObject(Object& obj, size_t index) {
if (isIndexOutOfRange(index))
throw std::out_of_range("Oops, index is out of range!");
availableIndexes.push_back(index);
objs[index] = obj;
}
Object& getObjectAtIndex(size_t index) const {
if (isIndexOutOfRange(index))
throw std::out_of_range("Oops, index is out of range!");
auto it = find(availableIndexes.begin(), availableIndexes.end(), index);
if (it == availableIndexes.end())
throw no_object("Oops, the object for this index is not set!");
return objs[index];
}
~Storage() {
free(objs);
}
private:
bool isIndexOutOfRange(size_t index) const noexcept {
Object* indexPointer = objs + sizeof (Object) * index;
if (indexPointer > lastPointer)
return true;
return false;
}
vector<size_t> availableIndexes;
Object* objs;
Object* lastPointer;
};
int main()
{
Storage storage(3);
{
cout << "1" << endl;
Object obj = Object("lambo");
cout << "2" << endl;
Object& objRef = obj;
cout << "3" << endl;
storage.storeObject(objRef, 2);
}
cout << "4" << endl;
Object savedObject = storage.getObjectAtIndex(2);
cout << "Information from stored object is " << savedObject.getInformation() << endl;
return 0;
}
有趣的是我有下一个输出:
1
Object constructor!
2
3
Object destructor!
4
Copy constructor!
Information from stored object is lambo
Object destructor!
该程序存储对对象的引用,然后我们可以获取它们。据我所知,在删除引用指向的对象后,引用变得不可用并且它指向垃圾。
这是我的问题:
1. 我可以这样使用引用吗?安全吗?
2. 为什么要调用拷贝构造函数?
3. 我的代码是否存在其他问题?
4. 如何修正这个程序是正确的?
提前致谢。
【问题讨论】:
-
删除后,它在“踢足球时不允许使用双手”的意义上确实变得不可用。踢球的时候手还是可以用的,就是违反规则
-
下次请尝试提供MCVE。
storeObject、getObjectAtIndex或getObjectAtIndex之类的东西根本与问题无关。请省略任何分散实际问题的内容 -
这会导致未定义的行为,这意味着任何事情都可能发生。您对行为的期望不正确
-
@Oleg 您确实需要在复制分配给它们之前创建这些对象(不是真的,这只是未定义的行为)。请参阅 user2079303 的答案。如果你想坚持使用
malloc,你至少应该在复制分配之前使用一个placement-new。您也可以查看std::aligned_storage而不是malloc。 -
“他没死,法官大人!他就在那儿,我可以戳他,他还有衣服、钱包和所有东西,所以他一定还活着。”
标签: c++ c++11 exception reference stl