我试图做类似的事情
class O has a child E
Run Code Online (Sandbox Code Playgroud)
我宣布变量
O xyz = new E();
Run Code Online (Sandbox Code Playgroud)
但是如果我调用xyz.method(),我只能调用类O的方法,而不是E的,所以我可以通过
E xyz2 = (E) xyz;
Run Code Online (Sandbox Code Playgroud)
我的问题是 - 你能否在不声明新变量的情况下这样做?就像是:
O xyz = new E();
xyz = (E) xyz;
Run Code Online (Sandbox Code Playgroud)
现在我可以使用xyz.method()来调用E的方法
有没有办法在java中这样做?
public class Animal{
int n = 5;
public static void main(String[] args) {
Animal a = new Animal();
Animal ah = new Horse();
Horse h = new Horse();
System.out.println(h.n); // prints 7
System.out.println(ah.n); // prints 5
h = (Horse) ah;
System.out.println(h.n); // prints 7
}
}
class Horse extends Animal{
int n = 7;
}
Run Code Online (Sandbox Code Playgroud)
为什么h.n
还要打印7 h = (Horse) ah
?在赋值之后它应该指向同一个ah
点,n字段指向5?
基类MessageHandler
具有派生类.他们想把信息传递给对方.消息可以是不同的类,但可以使其共享基类.每个人如何MessageHandler
避免向下传播收到的消息?是否有可能receiveMessage
在MessageHandler上做一些具有模板参数化虚拟函数效果的东西?
本质上,我试图用不向下转换的东西替换下面的代码,并且希望是编译时的东西:
// ...
virtual void MessageHandler::receiveMessage(Message &msg) = 0;
// ...
// to receive a message
void DerivedMessageHandler::receiveMessage(Message& msg)
{
switch (msg.MsgType()) // enum
{
case Message::MessageType::A:
MessageA& = dynamic_cast<MessageA&>(msg);
break;
case Message::MessageType::B:
MessageB& = dynamic_cast<MessageB&>(msg);
break;
default:
// don't process unknown messages
break;
}
}
// to send a message
list<MessageHandler> mhList;
// populate list
for (MessageHandler& mh : mhList)
{
mh.receiveMessage(msg);
}
Run Code Online (Sandbox Code Playgroud)
我知道我不能这样做,但有点像
template <typename M>
void MessageHandler::receiveMessage(M& msg) {}
Run Code Online (Sandbox Code Playgroud)
每个人都 …
c++ templates design-patterns downcast template-specialization
我有一个设计问题,我不知道如何以最好的方式处理.我希望我的代码能够成为未来的证明,而且仍然不会变得混乱和复杂(极客的困境).
目前我的设计有以下设置
derived class D derived class E
^ ^
| |
derived abstract class B -> derived class C
^ ^
| |
Abstract Base class A
Run Code Online (Sandbox Code Playgroud)
类B
从类不同A
,类D
和类E
从类不同B
和C
从类不同A
.
由于这些类不同,我需要使用dynamic_cast
运算符.
A* a1 = new class C;
C* c1 = dynamics_cast<C*>(a1);
if(c1){ //Success!!!}
...
Run Code Online (Sandbox Code Playgroud)
如你所见,我会想要使用dynamic_cast
很多!我需要尝试找到一种很好的方法来做到这一点,而不是if()
额外的语句.
这样做有一个简洁的方法吗?我似乎记得在Scott Meyers的书中看到了一些东西,但是我不在家,一两个星期都无法访问它.
任何参考/示例将非常感激.
此外,如果需要,我可以将类B
变成一个接口,这将是一种解决方案
B* d1 = new D;
B* e1 = new E; …
Run Code Online (Sandbox Code Playgroud) 我们可以考虑将值类型转换(如int转换为浮动转换为upcasting)和float转换为int作为向下转换吗?我相信当我们谈论向上转发和向下倾斜时,我们特别指的是参考转换.
我怀疑在C++中向下转换对象.
这是一个例子:
class A { }
class B : public A {
public:
void SetVal(int i) { _v = i; }
private:
int _v;
}
A* a = new A();
B* b = dynamic_cast<B*>(a);
b->SetVal(2);
Run Code Online (Sandbox Code Playgroud)
这个例子会发生什么?我们正在修改一个基础分支,就好像它是一个孩子......它如何与记忆相关?
使用此演员......是否像创建B的实例并复制A的值?
谢谢
给定以下代码,我有一个问题:
class A{}
class B extends A {}
class C extends B{}
public class Test {
public static void main(String[] args) {
A a = new A();
A a1=new A();
B b = new B();
// a=b;// ok
// b=(B)a;// ClassCastException
// a=(A)a1; // ok
// a=a1; // ok
a=(B)a1; // compiles ok, ClassCastException
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是粗体字。我的理解是,对于要编译的代码,只需要满足这些类在相同的层次结构中,并因此可以工作(在树上进行隐式强制转换,在树上进行显式强制转换)即可。每当我遇到ClassCastException时,是因为引用指向树上的一个对象,例如,指向B类型的对象的B类型的引用。
问题所在的行似乎是指向类型A的对象的类型A的引用。强制转换为(B)显然是导致ClassCastException的原因。有人可以解释一下如何做到这一点吗?
注意:如果a1指向B类型的对象,则它将起作用(刚刚对其进行了测试)。因此,对于编译器,向下转换是合法的,并且如果引用指向正确类型的对象,则可以毫无例外地执行该向下转换。
通过将A ref a1强制转换为B并将其分配给a,看来A ref a不再期望引用类型A的对象,而是B?
谢谢,肖恩。
PS我知道这有点不寻常,正在准备Java认证。通常,我们向下转换为左侧的类型,例如b =(B)a; (并且我可以看到为什么给出了ClassCastException)。
我有以下使用SWIG暴露给Python的c ++类(简化):
struct Component
{
virtual void update();
}
struct DerivedComponent : public Component
{
void update() { cout << "DerivedComponent::update()" << endl; }
void speak() { cout << "DerivedComponent::speak()" << endl; }
}
class Entity
{
public:
Component* component(const std::string& class_name)
{
return m_components[class_name];
}
private:
std::unordered_map<std::string, Component*> m_components;
}
Run Code Online (Sandbox Code Playgroud)
现在,在Python中,我可以成功调用component("DerivedComponent").update()
Entity实例。但是,component("DerivedComponent").speak()
由于返回的类型component("DerivedComponent")
报告为,因此我无法调用<class 'module.Component'>
。
component()
为了调用中定义的方法,我显然需要转换函数的结果DerivedComponent
。我曾希望Swig能像我相信Boost.Python一样执行自动向下转换。
缺少在c ++中定义一堆类型转换函数并将其公开给Python的方法,是否有使用Swig或Python进行向下转换的更好的解决方案?我有什么选择?
使用传统的中等规模项目.我已经使用Decorator模式实现了一个功能,除了它打破使用从接口到实现的向下转换的糟糕代码之外,它工作得很好.问题是:是否有任何工具或编译器标志或其他东西,可以帮助我找到使用向下转换的所有情况.我可以找到所有类型的所有案例.
我有一些代码来阐述我的问题:
曾经有
interface IComponent {}
class Concrete : IComponent {}
...
IComponent obj = new Concrete()
Run Code Online (Sandbox Code Playgroud)
现在
interface IComponent {}
class Concrete : IComponent {}
class Decorator : IComponent
{
private IComponent _imp = new Concrete()
}
...
IComponent obj = new Decorator()
Run Code Online (Sandbox Code Playgroud)
将obj转换为Concrete时出现错误代码,如(Concrete)obj.
说我有这些课程:
struct Parent {};
struct Child : public Parent {
void func() {}
};
Run Code Online (Sandbox Code Playgroud)
现在说我想创建一个这样的函数:
void foo(Parent* arg) {
auto child = dynamic_cast<Child*>(arg);
if(child != nullptr) child->func();
}
Run Code Online (Sandbox Code Playgroud)
但显然这显然会给我错误:
dynamic_cast
:Parent
不是多态类型
所以我不能做这dynamic_cast
一步,是否有一种方法可以验证arg
实际上是Child*
在运行时?
downcast ×10
c++ ×5
inheritance ×3
java ×3
polymorphism ×3
c# ×2
dynamic-cast ×1
object ×1
oop ×1
python ×1
swig ×1
templates ×1
value-type ×1