没有共享所有权的Getters

Jon*_*han 1 c++ getter

如何编写一个无法删除的getter?我想拥有变量而不是分享它们.在这里和那里读书我发现无论我什么回来,记忆都可以被释放

但我定义它,这是真的吗?

引用,const指针,无论如何,调用getter的函数都可以删除它,我的私有变量不会被取消但是内存坏了,对吧?

我想开发一个getter,我可以返回我的私有变量,并确保被调用者不能删除它...

我担心,在内部使用私有变量时,被调用者已经破坏了它,然后它在我的内部下一次尝试使用它时崩溃了我的程序

在第一次尝试中我不想使用提升,因为我试图从这个项目中学到最多,如果没有其他方式可以使用提升,或者如果反过来太复杂/多工作

谢谢,

我的另一个问题并没有真正集中,所以我再次这样做了,问这里问题不是问题,对吧?=]

jal*_*alf 5

取决于你的意思.只要有指针,就可以调用delete它.

如果你有一个引用,你可以获取它的地址,它会给你一个指针

无论如何,如果你有这个类,例如:

class X {
  int getByVal() { return i; } // returns a copy of i
  int& getByRef() { return i; } // returns a reference to i
private:
  int i;
};
Run Code Online (Sandbox Code Playgroud)

然后,作为您班级的用户,我没有明显的方法来删除您的数据.我可以做以下事情:

X x;
int j = x.getByVal();
int& k = x.getByRef();
j = 42; // doesn't affect x.i because we returned a copy
k = 42; // sets x.i to 42, because k is a reference
Run Code Online (Sandbox Code Playgroud)

我没有明显的方法可以删除类成员.当然,我可以这样做:

delete &j;
delete &k;
Run Code Online (Sandbox Code Playgroud)

(当然,这些都不会做任何有意义的事情,但是他们会编译)但我不会偶然这样做.如果你没有返回一个指针,很明显我不应该取得数据的所有权.

"保护你的代码免受Murphy,而不是Machiavelli"通常是一个很好的经验法则.如果他们尝试,您无法阻止人们破坏您的代码.你应该担心的是阻止他们意外地做这件事.

编辑
回复您在问题下的评论:

正如我所说,我正在学习......副本认为被调用者必须释放返回变量的内存,这对被调用者来说更麻烦(甚至认为它是我= p),所以我不是在谈论概念但写作的简单性......再次,我是这个记忆的新手.我正在使用C#,PHP等进行开发.很久以前,我在使用CircleMUD学习时曾经在C中开发过

不,不必手动删除副本.局部变量超出范围时会自动删除.所以在上面的例子中,j是类成员的副本i.当调用函数返回时,j将自动删除.

希望有所帮助.C++中的变量生命周期规则并不是很复杂,但要使它们正确是非常重要的,因为很多代码依赖于它们.

void foo()
{
  int i = 0; // allocate a local (on the stack) int, and initialize it to 0
  int* p = new int(1); // allocate an int on the heap, and initialize it to 1
  int j = i; // create a *copy* of i. Now we have two ints on the stack
  int k = *p; // create a copy of the int pointed to by p. k is also on the stack, so even though it was copied from a heap-allocated variable, k does not have to be manually deleted
  int* q = p; // create a copy of p. q is not a separate pointer, which points to the *same* heap-allocated integer.
}
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,foo返回时会自动清除所有副本.我们手动做的唯一事情是删除我们在堆上分配的整数.双方pq指向它,但我们只能一次删除对象.但是i,j,k,p,和q都是局部变量,声明在堆栈上.当函数返回时,每个都被清理.对于原始类型(例如ints和指针),实际上不必发生任何事情(它们没有析构函数).当它们超出范围时,它们就会消失 - 即使它们指向一些重要的东西,比如堆分配的对象,例如整数.

对于非POD对象,当它们超出范围时,它们的析构函数被调用,因此它们也可以很好地清理它们.因此,即使我们使用的是比int上面更复杂的类型,上面的工作也会很好.我们仍然可以复制非POD对象并按值传递它们.

我希望这有助于澄清一些事情.

  • +1是为了参考萨特的"墨菲与马基雅维利"的建议 (2认同)