Modfoo
Modfoo

Reputation: 97

Comparing objects in C and C++

I'm working on a project where I should instrument a program (written in C and C++) by inserting a print statement before the statements that respect some criteria. Then, I should compare those values for different executions. Since in C there are structures, while in C++ one can also define classes, I was wondering if there is a particular method that:

  1. Permits to print primitives as well as complex data structures.
  2. Permits to compare those values, for different executions, based on the format used by the print module (point 1.).

Just an example to clarify my question. Suppose that I have two different executions with this data structure:

struct Point {
   int x, y;
}

int main() {
    int k = random();
    Point p = foo(k);
    some_print(p); // Print the value of 'p' in a file

    return 0;
}

and then, another module will compare the two values of the point 'p' generated with the two executions.

Upvotes: 0

Views: 1867

Answers (2)

lorro
lorro

Reputation: 10880

The pragmatic C++-way of printing an object is defining a friend function:

std::ostream& operator<<(std::ostream& os, const Point& point) {
    return os << "(" << point.x << "," << point.y << ")";
}

It's usually class-specific so you need to implement it yourself; however, you might use some form of reflection. Particularly interesting is a CppCon-talk from Antony Polukhin [1] which gives reflection for POD types (like Point above). Generic reflection without external tools is N/A yet (as of 2016), there's a proposal on it. If you can't / don't want to wait, you can do multiple things:

  1. Parse C++ code: ctags comes to mind.

  2. Macros: It's relatively easy to write a FIELDS macro that defines a reflection class and the fields.


FIELDS(
    (int)x,
    (int)y
)

  1. Tuples: Works only if you define all your fields on the same inheritance level. Inherit privately from a std::tuple<> which contains all your fields. Make const and optionally non-const getters for fields in terms of std::get<>. Then you can iterate over the types of your tuple.

(Would love to add more - pls. write comments if you have ideas.)

All the reflection methods also give you operator==() basically for free. Note that it's more pragmatic to add operator<() when possible. The former can be defined in terms of the first (albeit suboptimally: a == b iff !(a < b) && !(b < a) ) and the latter gives you std::set<> and std::map<>. Or you can do all the comparisons in terms of reflection.

[1] https://www.youtube.com/watch?v=abdeAew3gmQ

Upvotes: 1

user3270587
user3270587

Reputation:

what you could do in c++, is to implement an equals method in your specific class. That way what you could do is have a boolean equals() method, that checks if the objects are similar. object1.equals(object2) could return either true or false.

to give an example with this answer, take a look at the following(an example i found online):

class car
{
private:
    std::string m_make;
    std::string m_model;

    bool operator== (const Car &c1, const Car &c2)
    {
        return (c1.m_make== c2.m_make &&
                c1.m_model== c2.m_model);
    }
}

something like this should be implemented in your own class.

Upvotes: 0

Related Questions