Simple Polymorphism cast not working

By : Vidak
Source: Stackoverflow.com
Question!

I have a class SourceComponent, and its derived class, PeriodicSourceComponent. Implementations are:

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();
};

and

 #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();
};

When I try in some different class/method to do:

SourceComponent* s = new PeriodicSourceComponent;

it won't let me, sayin "a value of type periodicblabla cant be assigned to value of type sourceblabla". Why?

Edit:

Ok, in my main it looks lke this:

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

And implementations of both classes:

source.cpp:

 #include "source_component.h"

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

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

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

and 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;

}

and its not working... (outputState is a member of class Component, base class of SourceComponent)

and the error message: A value of type "PeriodicSourceComponent*" cannot be assigned to a value of type "SourceComponent*".

Important Edit When I try to compile, the actual compiler error is at PeriodicSourceComponent declaration, it says: "Base class undefined".

and also, I have two other derived classes from SourceComponent, but I don't see how they could interfere with this one..

EDIT 4 Ok so I figured out what causes the error, you were right of course, it something else I didn't post. I have class VisitorSources, heres definition:

#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

And its implementation is not yet written:

#include "visitor_sources.h"

void visitSource(int type, float time)
{
}


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

When I comment out the entire Visitor class and implementation, the above-mentioned errors are gone for some reason. I have no idea why...

The only error that remains is that when I try to use s->frequency, it says that frequency is not a member of SourceComponent, which is true, but it is a member of PeriodicSourceComponent, which is why I used the cast in the first place..

Finally, here's the Component class, the main class for all almost all other classes in the project :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

And implementation:

#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;
        }
    }
}
By : Vidak


Answers

Are you using include guards in all your header files?

Not having them can cause the kinds of problems you're seeing.

By : kfmfe04


Three guesses:

  • You copied and pasted code between header files and forgot to change the #include guards.
  • You use precompiled headers and included something before the #include "stdafx.h".
  • If you use precompiled headers, try deleting the .pch file.
By : Henrik


This video can help you solving your question :)
By: admin