【问题标题】:Simple Polymorphism cast not working简单的多态性转换不起作用
【发布时间】:2012-02-28 17:54:40
【问题描述】:

我有一个类SourceComponent,以及它的派生类PeriodicSourceComponent。 实现是:

class SourceComponent : public Component
{
protected:
    friend class UserInterface;
    friend void readInput();
public:
    virtual int returnType();
    virtual int propagateLogic();
    virtual void sourcePropagation(float);

    virtual void accept(VisitorSources&);
    SourceComponent();
};

 #include "source_component.h"

class PeriodicSourceComponent : public SourceComponent
{
private:
    int frequency;
    friend void main();
    friend void readInput();
    friend class UserInterface;
public:
    void sourcePropagation(float);
    int returnType();
    PeriodicSourceComponent();
};

当我尝试一些不同的类/方法时:

SourceComponent* s = new PeriodicSourceComponent;

它不会让我说“类型为periodblabla 的值不能分配给类型为sourceblabla 的值”。为什么?

编辑:

好的,在我的主要看起来像这样:

#include "source_component.h"
#include "periodic_source_component.h"
void main()
{
     SourceComponent* s = new PeriodicSourceComponent;
}

两个类的实现:

source.cpp:

 #include "source_component.h"

    SourceComponent::SourceComponent()
    {
         outputState = -1;
    }

    int SourceComponent::propagateLogic()
    {
        return 1;
    }

    int SourceComponent::returnType()
    {
        return 5;
    }

和periodic.cpp

#include "periodic_source_component.h"

PeriodicSourceComponent::PeriodicSourceComponent()
{
    outputState = 0;

}

int PeriodicSourceComponent::returnType()
{
    return 3;
}

void PeriodicSourceComponent::sourcePropagation(float time)
{
    float t = time, period;
    period = 1000000/frequency;
    if(t > period)
    {
        while(t >= period)
            t -= period;
    }
    if(t <= (period/2))
            outputState = 0;
        else 
            outputState = 1;

}

而且它不工作...(outputState 是 Component 类的成员,SourceComponent 的基类)

以及错误信息:A value of type "PeriodicSourceComponent*" cannot be assigned to a value of type "SourceComponent*".

重要编辑 当我尝试编译时,实际的编译器错误在 PeriodicSourceComponent 声明中,它说:“基类未定义”。

此外,我还有两个来自 SourceComponent 的派生类,但我看不出它们会如何干扰这个..

编辑 4 好的,所以我弄清楚了导致错误的原因,您当然是对的,这是我没有发布的其他内容。我有类 VisitorSources,这是定义:

#ifndef __VISITOR_SOURCES_H__
#define __VISITOR_SOURCES_H__

#include "component.h"
#include "impulse_source_component.h"
#include "arbitrary_source_component.h"
#include "periodic_source_component.h"

class VisitorSources
{
protected:
    VisitorSources();

public:
    virtual void visitImpulseSource(ImpulseSourceComponent*);
    virtual void visitArbitrarySource(ArbitrarySourceComponent*);
    virtual void visitPeriodicSource(PeriodicSourceComponent*);
    void visitSource(int, float);
};


#endif

而且它的实现还没有写出来:

#include "visitor_sources.h"

void visitSource(int type, float time)
{
}


void VisitorSources::visitArbitrarySource(ArbitrarySourceComponent* a)
{
}

当我注释掉整个访问者类和实现时,上述错误由于某种原因消失了。我不知道为什么...

剩下的唯一错误是当我尝试使用 s->frequency 时,它说频率不是 SourceComponent 的成员,这是真的,但它是 PeriodicSourceComponent 的成员,这就是我使用演员表的原因首先..

最后,这是 Component 类,项目中几乎所有其他类的主类:P

#ifndef __COMPONENT_H__
#define __COMPONENT_H__

#include <iostream>
#include <vector>

class Component
{
    friend class UserInterface;
    friend void readAndSimulate();
protected:
    Component();
    int numOfInputs;
    int numOfOutputs;
    std::vector<Component*> inputs;
    std::vector<Component*> outputs;
    friend void main();
    float lengthOfSimulation;
    int typeIfSource;


public:
    int outputState;
    virtual int propagateLogic() = 0;
    virtual int returnType();

    int beginPropagation();
    virtual void sourcePropagation(float);

    ~Component();


};

#endif

及实施:

#include "component.h"
#include <conio.h>


Component::Component()
{
}

int Component::beginPropagation()
{
    std::vector<Component*>::const_iterator iter = outputs.begin();

    for(;iter<outputs.end();++iter)
    {
        if ((*iter)->outputState == -2)
        {
            (*iter)->outputState = outputState;
            return (*iter)->outputState;
        }
    }

    std::vector<Component*>::const_iterator it = outputs.begin();
    int finishedCycle, x;
    while(1)
    {
        finishedCycle = 1;
        for(; it < outputs.end(); ++it)
        {
            x = (*it)->propagateLogic();
            if(!x)
                finishedCycle = 0;
        }
        if(finishedCycle) break;
        it = outputs.begin();
    }
    it = outputs.begin();
    for(;it<outputs.end();++it)
        (*it)->beginPropagation();
}


int Component::returnType()
{
    return 0;
}

void Component::sourcePropagation(float)
{
}


Component::~Component()
{
    std::vector<Component*>::const_iterator it = inputs.begin();
    for(; it < inputs.end(); ++it)
    {
        if((*it) != NULL)
        {
            delete *it;
            Component* p = *it;
            p = NULL;
        }
    }
    it = outputs.begin();
    for(; it < inputs.end(); ++it)
    {
        if((*it) != NULL)
        {
            delete *it;
            Component* p = *it;
            p = NULL;
        }
    }
}

【问题讨论】:

  • 你能提供一个显示相同行为的独立测试用例吗?在我看来,您的真实代码看起来有些不同,也许您改为使用S s = new P;
  • 确实,这应该像 PlasmaHH 建议的那样工作 - 如果您发布更多代码和实际的错误消息,我们会帮助您
  • 你的基类应该有一个virtual析构函数。
  • @PlasmaHH 这就是我认为相关的所有代码。我只能从 Component 类中添加代码,Source 的基类
  • @TonyTheLion 添加了虚拟析构函数,但这并没有消除错误

标签: c++ oop class inheritance polymorphism


【解决方案1】:

您是否在所有头文件中使用include guards

没有它们可能会导致您遇到的各种问题。

【讨论】:

  • 是的,到处都有警卫......当我删除访客类时,一切正常......
  • 好吧,那个文件也不太对 - visitSource() 应该是 VisitorSources::visitSource(),因为它是一个成员函数。
  • 是的,但是我仍然没有在任何地方使用它,现在我已经改变了它,问题仍然存在:)
  • 好吧,ideone.com/8LSZC 编译得很好——所以你的代码有问题。使示例代码越来越接近您所拥有的,直到您可以重现错误 - 如果您这样做,我保证您会发现错误。
【解决方案2】:

三种猜测:

  • 您在头文件之间复制和粘贴代码,却忘记更改 #include 保护。
  • 您使用预编译的标头并在#include "stdafx.h" 之前包含一些内容。
  • 如果您使用预编译头文件,请尝试删除 .pch 文件。

【讨论】:

    猜你喜欢
    • 2015-10-06
    • 2013-12-15
    • 2020-09-18
    • 2023-03-13
    • 2022-12-14
    • 2013-06-04
    • 1970-01-01
    • 2018-05-23
    • 2012-04-16
    相关资源
    最近更新 更多