Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6363903
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 25, 20262026-05-25T00:05:47+00:00 2026-05-25T00:05:47+00:00

I’m finding it difficult to describe this problem very concisely, so I’ve attached the

  • 0

I’m finding it difficult to describe this problem very concisely, so I’ve attached the code for a demonstration program.

The general idea is that we want a set of Derived classes that are forced to implement some abstract Foo() function from a Base class. Each of the derived Foo() calls must accept a different parameter as input, but all of the parameters should also be derived from a BaseInput class.

We see two possible solutions so far, neither we’re very happy with:

  1. Remove the Foo() function from the base class and reimplement it with the correct input types in each Derived class. This, however, removes the enforcement that it be implemented in the same manner in each derived class.

  2. Do some kind of dynamic cast inside the receiving function to verify that the type received is correct. However, this does not prevent the programmer from making an error and passing the incorrect input data type. We would like the type to be passed to the Foo() function to be compile-time correct.

Is there some sort of pattern that could enforce this kind of behaviour? Is this whole idea breaking some sort of fundamental idea underlying OOP? We’d really like to hear your input on possible solutions outside of what we’ve come up with.

Thanks so much!

#include <iostream>

// these inputs will be sent to our Foo function below
class BaseInput {};
class Derived1Input : public BaseInput { public: int   d1Custom; };
class Derived2Input : public BaseInput { public: float d2Custom; };

class Base
{
public:
    virtual void Foo(BaseInput& i) = 0;
};

class Derived1 : public Base
{
public:
    // we don't know what type the input is -- do we have to try to cast to what we want
    // and see if it works?
    virtual void Foo(BaseInput& i) { std::cout << "I don't want to cast this..." << std::endl; }

    // prefer something like this, but then it's not overriding the Base implementation
    //virtual void Foo(Derived1Input& i) { std::cout << "Derived1 did something with Derived1Input..." << std::endl; }
};

class Derived2 : public Base
{
public:
    // we don't know what type the input is -- do we have to try to cast to what we want
    // and see if it works?
    virtual void Foo(BaseInput& i) { std::cout << "I don't want to cast this..." << std::endl; }

    // prefer something like this, but then it's not overriding the Base implementation
    //virtual void Foo(Derived2Input& i) { std::cout << "Derived2 did something with Derived2Input..." << std::endl; }
};

int main()
{
    Derived1 d1; Derived1Input d1i;
    Derived2 d2; Derived2Input d2i;

    // set up some dummy data
    d1i.d1Custom = 1;
    d2i.d2Custom = 1.f;

    d1.Foo(d2i);    // this compiles, but is a mistake! how can we avoid this?
                    // Derived1::Foo() should only accept Derived1Input, but then
                    // we can't declare Foo() in the Base class.

    return 0;
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-25T00:05:48+00:00Added an answer on May 25, 2026 at 12:05 am

    Since your Derived class is-a Base class, it should never tighten the base contract preconditions: if it has to behave like a Base, it should accept BaseInput allright. This is known as the Liskov Substitution Principle.

    Although you can do runtime checking of your argument, you can never achieve a fully type-safe way of doing this: your compiler may be able to match the DerivedInput when it sees a Derived object (static type), but it can not know what subtype is going to be behind a Base object…

    The requirements

    1. DerivedX should take a DerivedXInput
    2. DerivedX::Foo should be interface-equal to DerivedY::Foo

    contradict: either the Foo methods are implemented in terms of the BaseInput, and thus have identical interfaces in all derived classes, or the DerivedXInput types differ, and they cannot have the same interface.

    That’s, in my opinion, the problem.

    This problem occured to me, too, when writing tightly coupled classes that are handled in a type-unaware framework:

    class Fruit {};
    class FruitTree { 
       virtual Fruit* pick() = 0;
    };
    class FruitEater {
       virtual void eat( Fruit* ) = 0;
    };
    
    class Banana : public Fruit {};
    class BananaTree {
       virtual Banana* pick() { return new Banana; }
    };
    class BananaEater : public FruitEater {
       void eat( Fruit* f ){
          assert( dynamic_cast<Banana*>(f)!=0 );
          delete f;
       }
    };
    

    And a framework:

    struct FruitPipeLine {
        FruitTree* tree;
        FruitEater* eater;
        void cycle(){
           eater->eat( tree->pick() );
        }
    };
    

    Now this proves a design that’s too easily broken: there’s no part in the design that aligns the trees with the eaters:

     FruitPipeLine pipe = { new BananaTree, new LemonEater }; // compiles fine
     pipe.cycle(); // crash, probably.
    

    You may improve the cohesion of the design, and remove the need for virtual dispatching, by making it a template:

    template<class F> class Tree {
       F* pick(); // no implementation
    };
    template<class F> class Eater {
       void eat( F* f ){ delete f; } // default implementation is possible
    };
    template<class F> PipeLine {
       Tree<F> tree;
       Eater<F> eater;
       void cycle(){ eater.eat( tree.pick() ); }
    };
    

    The implementations are really template specializations:

    template<> class Tree<Banana> {
       Banana* pick(){ return new Banana; }
    };
    
    
    ...
    PipeLine<Banana> pipe; // can't be wrong
    pipe.cycle(); // no typechecking needed.
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I have this code: - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock { NSString *someString = [[NSString
I have some data like this: 1 2 3 4 5 9 2 6
I have a bunch of posts stored in text files formatted in yaml/textile (from
We're building an app, our first using Rails 3, and we're having to build
I am trying to loop through a bunch of documents I have to put
I'm making a simple page using Google Maps API 3. My first. One marker

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.