草庐IT

c++ - 调用基础运算符而不是派生运算符 - 正常行为?

coder 2024-02-23 原文

由于我目前正在使用 C++,我遇到了一个问题。代码如下:

#include        <iostream>

class Base {
public:
  virtual ~Base()                   {}


  virtual Base&         operator=(const Base& o)
  {
    std::cout << "Base operator called" << std::endl;
    return *this;
  }
};

class Derived : public Base {
public:
  virtual ~Derived() {}

  virtual Base&         operator=(const Base& o)

  {
    std::cout << "Derived operator called" << std::endl;
    return *this;
  }
};

int     main(void)
{
  Derived       a;
  Derived       b;
  Base&         c = a;
  Base&         d = b;

  a = b;                        // Base called                                                                                                                                 
  a = static_cast<Base>(b);     // Derived called                                                                                                                              
  a = d;                        // Derived called                                                                                                                              
  c = d;                        // Derived called                                                                                                                              
  return (0);
}

评论显示了我得到的输出。 最后 3 个结果非常可预测,但我无法理解第一个。

如第二个 (static_cast) 所示,当右操作数是基类时调用 Derived::operator=。然而,g++ (4.5.3-r2, gentoo Linux) 成功理解它必须使用 'Base' 类,但不会沿着继承树向下走。

所以我期待 Derived::operator= 被调用,或者 g++ 提示没有“Derived& Derived::operator=(const Derived&)”。有人可以向我解释这种行为吗? 谢谢!

最佳答案

Derived 类中有一个编译器生成 复制赋值,即operator=(Derived &),因为Derived: :operator=(Base const&) 不是 Derived 的复制赋值。如果您在代码中使用赋值,这不会阻止编译器生成复制赋值。

所以这一行:

 a = b;  // Base called     

调用编译器为 Derived 类生成的 operator=(Derived &),然后调用 operator=(Base const&)。因此 Base called 被打印出来。

实验:将此添加到 Derived 类:

Derived & operator=(Derived const & obj) : Base(obj)
{
   std::cout << "copy-assignment called" << std::endl;
   return *this;
}

现在,a=b 将导致打印:

Base called
copy-assignment called   

还要注意打印的顺序

希望能澄清您的疑问。


现在这个,

a = static_cast<Base>(b);  /// Derived called    

在功能上等同于此:

Base ___generated_tmp = static_cast<Base>(b);
a = ___generated_tmp;

表示,a = ___generated_tmp 调用 operator=(Base const&),因为 ___generated_tmp 的类型是 Base.

其余两个非常清楚,您似乎已经知道了。

关于c++ - 调用基础运算符而不是派生运算符 - 正常行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12146643/

有关c++ - 调用基础运算符而不是派生运算符 - 正常行为?的更多相关文章

  1. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

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

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

  3. ruby - 触发器 ruby​​ 中 3 点范围运算符和 2 点范围运算符的区别 - 2

    请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是

  4. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

  5. ruby-on-rails - 无法让 rspec、spork 和调试器正常运行 - 2

    GivenIamadumbprogrammerandIamusingrspecandIamusingsporkandIwanttodebug...mmm...let'ssaaay,aspecforPhone.那么,我应该把“require'ruby-debug'”行放在哪里,以便在phone_spec.rb的特定点停止处理?(我所要求的只是一个大而粗的箭头,即使是一个有挑战性的程序员也能看到:-3)我已经尝试了很多位置,除非我没有正确测试它们,否则会发生一些奇怪的事情:在spec_helper.rb中的以下位置:require'rubygems'require'spork'

  6. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  7. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  8. ruby - 调用其他方法的 TDD 方法的正确方法 - 2

    我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent

  9. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  10. 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.你能做的最好的事情是:

随机推荐