【问题标题】:Type casting (from derived class)类型转换(来自派生类)
【发布时间】:2011-04-06 10:48:13
【问题描述】:

我想在 c++ 中像 jquery-way 一样进行链式调用。样本:

$('#obj').getParent().remove();

所以,据我了解,类的每个方法都应该将指针返回给自己(this)。

在我调用基派生方法之前一切正常。代码:

class Base
{
   Base *base1() { return this; }
   Base *base2() { return this; }
};

class Derived : Base
{
   Derived *derived1() { return this; }
   Derived *derived2() { return this; }
};

Derived *obj = new Derived();
obj->derived1()->derived2(); // Everything is okay
obj->derived1()->base1()->derived2(); // Fail at second step

当然,base1 返回 Base 的指针。有什么方法可以进行自动投射?


UPD:也许这可以通过宏实现?喜欢

#define CORRECT_RETURN (this)

Base::base1() {
   return CORRECT_RETURN;
}

以这种方式。还是编译器不会看这样的构造?

【问题讨论】:

  • 这根本不是“jquery-way”的功能。当然,没有办法做你想做的事。您尝试在 Base 上调用的函数(在调用 base1() 之后)当然必须在 Base 的接口中。
  • 我不确定您要达到的目标。如果它是将调用链接在一起,您可以在不使用继承的情况下添加无限。如果目标是产生正确类型的返回,则需要研究协方差或重载类型转换。
  • 签名“base()”意味着你得到了一个指向基数的指针,这没有多大意义。应该更改方法名称以匹配它们所服务的任何功能,而不是简单地成为“this”指针的获取器。如果您想要“this”指针,只需跳过 getter。您仍然可以从任何函数返回“this”,并使用协方差(如 Tyler 建议的那样)。
  • 我怀疑base1base2 真的是方法的名称。它们很可能是匿名名称,仅表示它是在基类接口中声明的方法。因此,在派生类对象上调用函数时,返回指向派生类对象的指针应该没有语义问题。

标签: c++ class casting types


【解决方案1】:

是的。覆盖Derived 中的base1base2 方法,将它们的返回值从Base* 更改为Derived*,例如

class Derived : Base
{
   Derived *base1() { return this; }
   Derived *base2() { return this; }
   Derived *derived1() { return this; }
   Derived *derived2() { return this; }
};

这称为返回类型的协方差,在 C++ 中是合法的。

假设您想实际使用基类方法中实现的某些功能而不重复它,您可以执行以下操作:

class Derived : Base
{
   Derived *base1() { Base::base1(); return this; }
   Derived *base2() { Base::base2(); return this; }
   Derived *derived1() { return this; }
   Derived *derived2() { return this; }
};

在您问之前,不,您不能创建这样一种情况,即基类的每个派生类都使用具有适当协方差的返回类型自动覆盖 base1base2 方法。您每次都必须手动完成,否则编写大量的脚手架代码使其看起来像正在发生的事情,这通常比它的价值更麻烦。

【讨论】:

  • 不要忘记虚拟基础。正如定义的那样,你正在隐藏,所以你不会得到多态性。
  • 虚拟方法可能是一个像这样的层次结构的好主意,但实际上并不需要它来工作。 obj 是一个Derived*,所以obj->derived1() 是一个Derived*,所以obj->derived1()->base1() 调用Derived::base1(实际上返回一个Derived*)不管base1 是否是虚拟的。
  • @tyler-mchenry 好答案。请看更新好吗?
  • 不可能通过修改基类来实现,因为可能有无数个派生类。宏不会帮助你。如果您不想使用协方差,唯一的其他答案就是做一个标准的向下转换:dynamic_cast<Dervied*>(obj->derived1()->base1())->derived2(),但我假设您已经知道这一点并且想要语法上更好的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-01
  • 2022-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-15
相关资源
最近更新 更多