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

  • SEARCH
  • Home
  • 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 6162169
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 23, 20262026-05-23T21:36:24+00:00 2026-05-23T21:36:24+00:00

(This is sort of a long-winded question but I have summarized it at the

  • 0

(This is sort of a long-winded question but I have summarized it at the bottom.)

I want to write a class (in C++) that performs tests on objects of some unknown type deriving from a very skeletal base class. The idea is that an object of this class is initialized with an “expected” result and then called many times, saving the outcome and comparing it to the expected one. The whole package should look something like this:

struct test_input
{
  virtual ~test_input() = 0;
};

struct test_output
{
  virtual bool operator== (const test_output&) = 0;
  virtual ~test_output() = 0;
};

typedef test_output& (*test_function)(test_input&);

class test
{
  const test_input &data;
  const test_output &expected;
  test_output *result;

  test(test_input &i, test_output &o)
    : data(i), expected(o), result(NULL)
    {}

  bool operator() (test_function &trial)
    { return *(result = &trial(data)) == expected; }
};

// Example usage
class ti_derived : public test_input { /* ... */ };
class to_derived : public test_output { /* ... */ };
to_derived& some_function_one(ti_derived &arg) { /* ... */ }
to_derived& some_function_two(ti_derived &arg) { /* ... */ }

ti_derived ti; // Somehow initialized
to_derived correct; // Somehow determined
test test_object(ti, correct);
if (!test_object(&some_function_one)) {
  cout << "1: " << test_object.result;
}
if (!test_object(&some_function_two)) {
  cout << "2: " << test_object.result;
}    

My intention is that the same object of type test can be called repeatedly on many test_functions, which is why its member result must be a pointer rather than a reference: I can’t reassign a reference.

The problem is that the code for operator() is wrong: the left-hand side is not a reference to a test_output, so it is statically cast to the exact class test_output, which is purely virtual; however, I want operator== to be dynamically bound to the equality operator for type to_derived. As is, it will try to downgrade expected to the base type test_output and complain that I don’t have such an operator (and if I did, it would be the wrong one anyway). Note: switching the order of the operands would cause operator== to be that of to_derived, but then the compiler would complain that the type of the second argument was wrong.

I guess I could make test a template depending on types, say template <typename I, typename O>, replacing test_input and test_output in its code, but that is not so good because it fails to specify that I and O inherit the virtual functions I want (which is why I have those two classes in the first place).

It’s tempting, though sort of inelegant, to want to overload operator== on type test_output*, but that’s not legal, is it? I could make only one of the arguments a pointer, since expected can remain a reference type, but again: inelegant. This is not how I would write the code if I did not need result to be reassignable, and so it is not how I want to write the code.

If this were not in a class, I could just define a new reference variable every time I want to save a new result, but I can only have so many members. Syntactically, this sounds like a situation where I’d want a “pointer to a reference to test_output“, but that’s illegal also. (Either that, or something like a “rebind” operator for references.) A test_output ** is no good, since I want to ultimately be able to pass objects of (base) type test_output; if I do one dereference I just get a test_output *, but if I do two then the type is no longer dynamic.

So how do I do this? Specifically, I want:

  • to bind the equivalent of operator==(*result, expected) to the equality operator for the dynamic types of these things;

  • to be able to indicate to the compiler that those types are derived from test_output;

  • to be able to reassign result.

I am also wondering: in my sample usage, is it valid to use those function pointers as arguments to test_object? Their arguments can be dynamically typed but I don’t know whether that means the function type itself has an automatic conversion to the function type taking and returning the respective base types. If not, how would I indicate a function of this dynamically-typed signature?

  • 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-23T21:36:25+00:00Added an answer on May 23, 2026 at 9:36 pm

    Sorry, but the design seems to be flawed in several aspects. First,

    typedef test_output& (*test_function)(test_input&);
    

    calls for trouble. Don’t return references to objects generated inside a function. The referenced object is destroyed, when the called function ends, so you will store in result the address of an object that does not exist anymore (dangling pointer). If you need polymorphic results, return them safely as shared_ptr<test_output>, which should also be the type of result.

    Concerning your list of questions (sorry for long answer):

    to bind the equivalent of operator==(*result, expected) to the equality operator for the dynamic types of these things;

    Yes, as you did. The equality test should be overridden for every class derived from test_output.

    to be able to indicate to the compiler that those types are derived from test_output;

    For comparing polymorphic objects for the left operand with polymorphic objects on the right hand side, welcome to the field of multi-methods. The problem boils down to: “When do you consider two objects as equal?” Should they have exactly the same type or can one belong to a subset of the other? Normally the Liskov substitution principle in object orientation means: A derived object can be substituted for a base object, since inheritance guarantees it has all base properties.
    To determine if expected to be of (at least) to_derived you need a downcast:

    bool to_derived::operator==(const test_output& expected)
    {
      if (to_derived* e = dynamic_cast<to_derived*>(&expected))
      {
        // compare all data fields, then
        return true; 
      }
      return false;
    }
    

    If you want to guarantee expected to be of exactly the same type, you should use RTTI first:

      if (typeid(*this) != typeid(expected)) return false;
    

    Derived objects are no consired of the same type. Maybe your compiler needs a switch to enable that.

    to be able to reassign result.

    Use a shared_ptr<test_output>, because it manages memory for dynamic objects.

    is it valid to use those function pointers as arguments to test_object? Their arguments can be dynamically typed but I don’t know whether that means the function type itself has an automatic conversion to the function type taking and returning the respective base types. If not, how would I indicate a function of this dynamically-typed signature?

    The function pointers does not need any conversion.
    But your test framework seems to be incomplete, since it may work only for standalone functions. What about methods? I would suggest a templated solution.

    I would seriously consider looking for an existing unit testing framework.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I know that this sort of question has been asked here before, but still
This question has been asked a number of times, I have noted, but none
Sorry this is such a long question but it touches on a general issue
I have an object model that looks like this: public MyObjectInJson { public long
I am mocking in this sort of situation: class A { public IB B
I have this sort of format asp.net MVC View -> Service Layer -> Repository.
I asked this sort of question before ( Application fails to dynamically _re_load JavaScript
I know this sort of code is not best practice, but nevertheless in certain
I have been working on this sort of ATM (With a maximum of 50
Does anyone have any experience with this sort of thing? I'm talking about applets

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.