标签: downcast

如何改变这种设计以避免垂头丧气?

假设我有一个从基类继承的对象集合.就像是...

   abstract public class Animal
    {

    }

    public class Dog :Animal
    {

    }

    class Monkey : Animal
    {

    }
Run Code Online (Sandbox Code Playgroud)

现在,我们需要喂养这些动物,但不允许他们知道如何喂养自己.如果他们可以,答案是直截了当的:

foreach( Animal a in myAnimals )
{
   a.feed();
}
Run Code Online (Sandbox Code Playgroud)

但是,他们不知道如何养活自己,所以我们想做这样的事情:

    class Program
{
    static void Main(string[] args)
    {
        List<Animal> myAnimals = new List<Animal>();

        myAnimals.Add(new Monkey());
        myAnimals.Add(new Dog());

        foreach (Animal a in myAnimals)
        {
            Program.FeedAnimal(a);
        }
    }

    void FeedAnimal(Monkey m) {
        Console.WriteLine("Fed a monkey.");
    }

    void FeedAnimal(Dog d)
    {
        Console.WriteLine("Fed a dog.");
    }

}
Run Code Online (Sandbox Code Playgroud)

当然,这不会编译,因为它会迫使垂头丧气.

感觉好像有一个设计模式或其他一些带有泛型的解决方案可以帮助我摆脱这个问题,但我还没有把手指放在它上面.

建议?

c# design-patterns overloading downcast

3
推荐指数
1
解决办法
2556
查看次数

编译时和运行时的Downcasting/Upcasting错误?

请检查以下程序.

我怀疑编译器何时会在编译器级别发出转换异常,何时它会在runtime

喜欢下面的程序,表达

我认为(Redwood) new Tree()应该在编译时失败,因为Tree不是Redwood.但它没有失败compile time,正如预期的那样失败runtime!!!

public class Redwood extends Tree {
     public static void main(String[] args) {
         new Redwood().go();
     }
     void go() {
         go2(new Tree(), new Redwood());
         go2((Redwood) new Tree(), new Redwood());
     }
     void go2(Tree t1, Redwood r1) {
         Redwood r2 = (Redwood)t1;
         Tree t2 = (Tree)r1;
     }
 }
 class Tree { }
Run Code Online (Sandbox Code Playgroud)

java inheritance casting type-conversion downcast

3
推荐指数
3
解决办法
4692
查看次数

haskell如何'向下'一个类型界面?

在oop中,例如java,当类型实际上是子时,我们只能将超类转发为类.

但是在haskell中,我们可以简单地将一个类型"转发"到该类型类的任何实例中.如fromInteger返回一个Num.从我的角度来看,它实际上是一个Int,所以它不能被"下载"到Float但它可以.

Prelude System.Random> :t fromInteger a
fromInteger a :: Num a => a
Prelude System.Random> fromInteger 12 :: Int
12
Prelude System.Random> fromInteger 12 :: Float
12.0
Run Code Online (Sandbox Code Playgroud)

另一个例子是改为RandomInt,Float甚至Bool

Prelude System.Random> let (a, g) = random (mkStdGen 12) :: (Int, StdGen)
Prelude System.Random> let (a, g) = random (mkStdGen 12) :: (Double, StdGen)
Prelude System.Random> let (a, g) = random (mkStdGen 12) :: (Bool, …
Run Code Online (Sandbox Code Playgroud)

haskell types downcast

3
推荐指数
1
解决办法
478
查看次数

在Swift中从Dictionary中读取时的Downcast元素

我正在尝试访问一个元素一个字典元素,并将其向下转换为AnyObject以外的类型,但不断得到相同的编译器错误:Could not find an overload for 'subscript' that accepts the supplied arguments.

我知道我可以使用两个if语句这样做:

if let x = dict["key"] {
    if let y = x as? String {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

但我觉得必须有一个比这更优雅的解决方案.对我来说最有意义的格式是:

if let x = dict["key"] as? String {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

但这只会导致上面提到的错误.我已经尝试了几十种变体,但似乎没有任何差异.这是在Swift中无法完成的吗?

dictionary downcast swift

3
推荐指数
1
解决办法
2001
查看次数

C++避免向下转发

我需要解析源代码.我已经确定了3种不同类型的标记:符号(运算符,关键字),litterals(整数,字符串等)和标识符.

我已经有了以下设计,其中有一个跟踪子类类型的基类,因此可以使用基类指针对其进行下载:

class Token
{
    type_e type; // E_SYMBOL, E_LITTERAL, E_TOKEN
};

class Symbol : public Token
{
    const symbol_e symbol;
};

class Litteral : public Token
{
    const Value value;
};

class Identifier : public Token
{
    const std::string name;
};
Run Code Online (Sandbox Code Playgroud)

我需要将这些类存储在一个令牌数组中,这就是为什么我需要它们有一个共同的基类.然后我像这样使用它们:

if( cur->type == E_SYMBOL && static_cast< const Symbol * >( cur )->symbol == E_LPARENT )
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

我可以创建虚函数isSymbol,isLitteral,isIdentifer,每个子类都会覆盖,但我仍然需要将基类指针向下转换为子类指针,以便我可以访问子类的特定数据.

人们说向下转换意味着界面可能存在缺陷,并且它使语法非常沉重,所以我想找到另一种方式,但我不能.有些人建议访问者模式,但我担心这会无用地复杂化代码,我甚至不明白我如何使用访问者模式来解决这个问题.

有人可以帮忙吗?谢谢 :)

c++ polymorphism inheritance subclass downcast

3
推荐指数
1
解决办法
1283
查看次数

向下转型 `vector&lt;Parent&gt;`

我的程序中存在向上转型和向下转型的问题。我有一个vector<Child>被传递给一个期望的函数const vector<Parent>& pp。到目前为止没有问题(编辑:显然有!请参阅评论)。但是,现在我想传递pp给一个期望的函数const vector<Child>& cc,但我不能这样做。

我应该如何做到这一点,同时我不赋予函数修改原始类的能力?您能否列出执行此操作的各种方法,最好列出它们的优缺点?

c++ class downcast

3
推荐指数
1
解决办法
1730
查看次数

Swift AnyObject转换

我创建了一些测试代码来显示我遇到的问题.

这在操场上编译很好,但是,当我尝试将它放入项目时,Xcode会给出以下警告:Treating a forced downcast to 'String' as optional will never produce 'nil'第30行.我有两个建议来解决这个问题:

  1. Use 'as?' to perform a conditional downcast to 'String',这绝对没有意义.但是,它确实编译时没有警告/错误,这看起来很奇怪,因为它将可选值分配给非可选类型String.

    当您不确定向下转换是否成功时,请使用类型转换运算符的条件形式(作为?).这种形式的运算符将始终返回一个可选值,如果无法进行向下转换,则该值将为nil.这使您可以检查成功的向下转发.

    来自Swift语言指南.

    除非它认为我可能想要分配nil转换失败(因此删除字典条目),这没有任何意义.特别是因为我确信它会成功,因为我确实只是检查它是否是一个String.

  2. Add parentheses around the cast to silence this warning,这似乎毫无意义,但确实使警告沉默.这似乎是一件奇怪的事情,但话说回来,这可能只是一种确认你真的想要做你想做的事情的糟糕方式.


哪个选项是对的,还是两个都没有?导致此警告的原因是什么?

types downcast optional swift anyobject

3
推荐指数
1
解决办法
859
查看次数

Java转换错误?

任何人都知道为什么编译器不能在'short'中输出值'7'?显式转换正在工作,但在传递参数时它不起作用!

class Alien {
    String invade(short ships) { return "a few"; }
    String invade(short... ships) { return "many"; }
}
public class Wind {
    public static void main(String [] args) {
        short temp = 7;
        System.out.println(new Alien().invade(7));
    }
}
Run Code Online (Sandbox Code Playgroud)

java casting downcast

2
推荐指数
1
解决办法
1235
查看次数

有没有副本可以向下传播shared_ptr?

#include <memory>

struct a {};
struct b : public a {};

std::shared_ptr<b> get()
{
    std::shared_ptr<a> temp(new b);
    return std::static_pointer_cast<b>(temp); // atomic ref-count inc/dec
}
Run Code Online (Sandbox Code Playgroud)

据我所知,downcast shared_ptr的唯一方法是static_pointer_cast.但是,它只需要const引用并创建参数的下载副本.如果可能的话,我想避免复制,因为复制构造和shared_ptr的破坏意味着原子递增/递减操作.

有一些移动构造函数采用shared_ptr的其他实例,但它们不支持向下转换.

是否可以避免以符合标准的方式复制?

c++ shared-ptr downcast c++11

2
推荐指数
1
解决办法
541
查看次数

当我们进行向下转换时,内部会发生什么?

我试图了解向下...这是我尝试过的......

class Shape
{
public:
    Shape() {}
    virtual ~Shape() {}
    virtual void draw(void)     { cout << "Shape: Draw Method" << endl; }
};

class Circle : public Shape
{
public:
    Circle(){}
    ~Circle(){}
    void draw(void)     { cout << "Circle: Draw Method" << endl; }
    void display(void)  { cout << "Circle: Only CIRCLE has this" << endl; }
};

int main(void)
{
    Shape newShape;
    Circle *ptrCircle1 = (Circle *)&newShape;
    ptrCircle1->draw();
    ptrCircle1->display();

    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

在这里,我通过将基类指针转换为派生类来进行向下转换.我的理解是......

Circle* ptrCircle1 -->  +------+ new Shape()
                        |draw()| …
Run Code Online (Sandbox Code Playgroud)

c++ casting virtual-functions downcast

2
推荐指数
1
解决办法
333
查看次数