草庐IT

c++ - 防止重新分配引用?

coder 2024-02-15 原文

考虑在某个地方的某个库中(我们无权更改),我们有一个 Counter 类:

class Counter {
    int count;
  public:
    Counter() : count(0) { }
    void bump() { ++count; }
    int getCount() const { return count; }
};

就其本质而言,它是可变的。如果它是 const,它就毫无值(value)。

在我们的代码中,我们“使用”了那个计数器。很糟糕。

#include <string>
#include <iostream>
#include <Counter.hpp>

using std::cout;
using std::endl;

void breakTheHellOutOfCounter(Counter &c) {
    // This is OK
    c.bump();

    // Oh noes!
    c = Counter();
}

int main() {
    Counter c;
    c.bump(); c.bump(); c.bump();
    std::cout << "Count was " << c.getCount() << std::endl;
    breakTheHellOutOfCounter(c);
    std::cout << "Count is now " << c.getCount() << std::endl;
}

请注意,breakTheHellOutOfCounter 用 Shiny 的新计数器覆盖了 main 的计数器,重置了计数。这会让来电者感到有些悲伤。 (想象一些更有害的事情发生,你会明白我要说的。)

我需要能够 bump c(因此,我需要它是可变的),但我希望 breakTheHellOutOfCounter() 由于尝试 替换 c。有没有一种方法可以改变事物(Counter 类除外)来实现这一点?

(我知道在最低级别上,这几乎是不可能执行的。我想要的是一种方法,以防止意外发生。)

最佳答案

在不修改计数器本身的情况下,我能看到的最干净的解决方案是这样的:

#include <string>
#include <iostream>
#include <Counter.hpp>

template <typename T>
struct Unbreakable : public T {
  Unbreakable<T>& operator=(const Unbreakable<T>&) = delete;
  Unbreakable<T>& operator=(Unbreakable<T>&&) = delete;

  template <typename ...Args>
  Unbreakable(Args&& ...args) : T(std::forward<Args>(args)...) {}
};

using std::cout;
using std::endl;

void breakTheHellOutOfCounter(Unbreakable<Counter> &c) {
    // this is ok
    c.bump();

    // oh noes!
    c = Counter();
}


int main() {
    Unbreakable<Counter> c;
    c.bump(); c.bump(); c.bump();
    std::cout << "Count was " << c.getCount() << std::endl;
    breakTheHellOutOfCounter(c);
    std::cout << "Count is now " << c.getCount() << std::endl;
}

这正确地给出了来自“哦不”行的错误。 (示例使用 C++11,但 C++98 解决方案类似)

这并不排除像这样的用法:

Counter& br = c;
br = Counter();

当然可以,但如果不修改 Counter 本身,我认为这是无法避免的。

关于c++ - 防止重新分配引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11821107/

有关c++ - 防止重新分配引用?的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  3. Ruby Koans about_array_assignment - 非平行与平行分配歧视 - 2

    通过ruby​​koans.com,我在about_array_assignment.rb中遇到了这两段代码你怎么知道第一个是非并行赋值,第二个是一个变量的并行赋值?在我看来,除了命名差异之外,代码几乎完全相同。4deftest_non_parallel_assignment5names=["John","Smith"]6assert_equal["John","Smith"],names7end45deftest_parallel_assignment_with_one_variable46first_name,=["John","Smith"]47assert_equal'John

  4. ruby-on-rails - active_admin 目录中的常量警告重新声明 - 2

    我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA

  5. ruby - 在 Ruby 中重新分配常量时抛出异常? - 2

    我早就知道Ruby中的“常量”(即大写的变量名)不是真正常量。与其他编程语言一样,对对象的引用是唯一存储在变量/常量中的东西。(侧边栏:Ruby确实具有“卡住”引用对象不被修改的功能,据我所知,许多其他语言都没有提供这种功能。)所以这是我的问题:当您将一个值重新分配给常量时,您会收到如下警告:>>FOO='bar'=>"bar">>FOO='baz'(irb):2:warning:alreadyinitializedconstantFOO=>"baz"有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会发生重新分配。 最佳答案

  6. ruby - 一个 YAML 对象可以引用另一个吗? - 2

    我想让一个yaml对象引用另一个,如下所示:intro:"Hello,dearuser."registration:$introThanksforregistering!new_message:$introYouhaveanewmessage!上面的语法只是它如何工作的一个例子(这也是它在thiscpanmodule中的工作方式。)我正在使用标准的ruby​​yaml解析器。这可能吗? 最佳答案 一些yaml对象确实引用了其他对象:irb>require'yaml'#=>trueirb>str="hello"#=>"hello"ir

  7. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  8. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  9. ruby - 使对象的行为类似于 ruby​​ 中并行分配的数组 - 2

    假设您在Ruby中执行此操作:ar=[1,2]x,y=ar然后,x==1和y==2。是否有一种方法可以在我自己的类中定义,从而产生相同的效果?例如rb=AllYourCode.newx,y=rb到目前为止,对于这样的赋值,我所能做的就是使x==rb和y=nil。Python有这样一个特性:>>>classFoo:...def__iter__(self):...returniter([1,2])...>>>x,y=Foo()>>>x1>>>y2 最佳答案 是的。定义#to_ary。这将使您的对象被视为要分配的数组。irb>o=Obje

  10. ruby-on-rails - 使用 Dragonfly 从 URL 分配图像 - 2

    我正在使用Dragonfly在Rails3.1应用程序上处理图像。我正在努力通过url将图像分配给模型。我有一个很好的表格:{:multipart=>true}do|f|%>RemovePicture?Dragonfly的文档指出:Dragonfly提供了一个直接从url分配的访问器:@album.cover_image_url='http://some.url/file.jpg'但是当我在控制台中尝试时:=>#ruby-1.9.2-p290>picture.image_url="http://i.imgur.com/QQiMz.jpg"=>"http://i.imgur.com/QQ

随机推荐