草庐IT

c++ - 私有(private)成员的常量访问器之间的比较

coder 2023-05-31 原文

这个问题的主要部分是关于为类内的私有(private)数据成员创建公共(public)只读访问器的正确且计算效率最高的方法。具体来说,利用 const type & 引用来访问变量,例如:

class MyClassReference
{
private:
    int myPrivateInteger;

public:
    const int & myIntegerAccessor;

    // Assign myPrivateInteger to the constant accessor.
    MyClassReference() : myIntegerAccessor(myPrivateInteger) {}
};

然而,目前解决这个问题的既定方法是利用一个常量“getter”函数,如下所示:

class MyClassGetter
{
private:
    int myPrivateInteger;

public:
    int getMyInteger() const { return myPrivateInteger; }
};

“getter/setter”的必要性(或缺乏)已经被反复讨论过,例如:Conventions for accessor methods (getters and setters) in C++然而,这不是当前的问题。

这两种方法都使用以下语法提供相同的功能:

MyClassGetter a;
MyClassReference b;    
int SomeValue = 5;

int A_i = a.getMyInteger(); // Allowed.    
a.getMyInteger() = SomeValue; // Not allowed.

int B_i = b.myIntegerAccessor; // Allowed.    
b.myIntegerAccessor = SomeValue; // Not allowed.

在发现这一点后,在互联网上没有找到任何相关信息,我问了我的几位导师和教授,哪些是合适的,每个人的相对优势/劣势是什么。但是,我收到的所有回复都很好地分为两类:

  1. 我从来没有想过,但使用“getter”方法,因为它是“已建立的实践”。
  2. 它们的功能相同(它们都以相同的效率运行),但使用“getter”方法,因为它是“已建立的实践”。

虽然这两个答案都是合理的,但他们都未能解释“为什么”让我不满意,并决定进一步调查这个问题。虽然我进行了几次测试,例如平均字符使用(它们大致相同)、平均打字时间(再次大致相同),但一项测试显示这两种方法之间存在极大差异。这是调用访问器并将其分配给整数的运行时测试。没有任何 -OX 标志(在 Debug模式下),MyClassReference 的执行速度大约快了 15%。但是,一旦添加了 -OX 标志,除了执行速度更快之外,这两种方法都以相同的效率运行。

因此我的问题有两个部分。

  1. 这两种方法有何不同?是什么导致仅使用某些优化标志时一种方法比其他方法更快/更慢?
  2. 为什么惯例是使用常量“getter”函数,而使用常量引用却鲜为人知,更不用说使用了?

正如评论所指出的,我的基准测试存在缺陷,与手头的问题无关。但是,对于上下文,它可以位于修订历史记录中。

最佳答案

问题 #2 的答案是,有时您可能想要更改类内部结构。如果你公开了所有属性,它们就是接口(interface)的一部分,所以即使你想出了一个不需要它们的更好的实现(比如,它可以快速重新计算值并减少每个属性的大小例如,现在拥有 1 亿个程序的程序现在使用的内存减少了 400-800 MB),您无法在不破坏相关代码的情况下删除它。

启用优化后,当 getter 的代码无论如何都只是直接成员访问时,getter 函数应该与直接成员访问没有区别。但是,如果您想更改值的派生方式以删除成员变量并即时计算值,则可以在不更改公共(public)接口(interface)的情况下更改 getter 实现(重新编译将使用 API 修复现有代码而无需更改代码最后),因为函数不受变量方式的限制。

关于c++ - 私有(private)成员的常量访问器之间的比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36562741/

有关c++ - 私有(private)成员的常量访问器之间的比较的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  3. ruby-on-rails - 未初始化的常量 Psych::Syck (NameError) - 2

    在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到ruby​​gems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决

  4. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  5. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  6. ruby - Ruby 的 Hash 在比较键时使用哪种相等性测试? - 2

    我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。

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

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

  8. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  9. 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

  10. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

随机推荐