简体   繁体   中英

Inheritance and friend functions, accessing protected members from base class

Let say that I have a big class Circle with a lot of members and functions. To proceed a large amount of data I decided to create class PotentialCirlce (with only 3 members - x, y, r), do most of preprocessing based on PotentialCirlce and in the last stage create objects Circle .

a) is it correct approach? do It influence on performance or rather should I use only Circle .

It seems to me that I can use inheritance:

class potentialCircle {
protected:
    point_t center;
    unsigned int radius;
public:
    potentialCircle(int a, int b, unsigned int r) : center{ point_t(a,b) }, radius{ r } {}
    potentialCircle() = delete;
    potentialCircle(const potentialCircle&) = default;
    potentialCircle(potentialCircle&&) = default;
    potentialCircle& operator=(const potentialCircle&) = default;
    potentialCircle& operator=(potentialCircle&&) = default;
    virtual ~potentialCircle() = default;
};

class Circle : public potentialCircle {
    // members detected based on Hough Circle Transform
    //point_t center;                           // coordinates of center point
    point_t alternative_center;                 // needed when center is out of frame
    //unsigned int radius;                      // radius

    // members calculated based on Flood Fill algorithm (more realistic)
    unsigned int area = 0;
    float diameter = 0;
    float perimeter = 0;
....
};

b) where should I put method which needs to compare two difference objects? one object of type Circle and one of PotentialCirle? currently, I have defined below function as part of Circle

bool Circle::is_greater(const std::pair<potentialCircle, int>& point_pair) const;

but I don't have access to protected data members of potentialCircle, although Circle is inheriting from potentialCircle. Maybe I should defined is_greater() as part of namepsace and make it a friend to Circle and potentialCircle.

Do you have better idea?

There are not really a good approach to compare objects of different types as it make little sense in practice. What would be the purpose of such comparisons.

Now even if you have a single class, if the ordering is not intransic to the type, it would be better to use an external class for sorting.

class CircleDiameterLess
{
public:
    bool operator()(const Circle &lhs, const Circle &rhs)
    {
        return lhs.diameter < rhs.diameter;
    }
};

That way, you can have multiple ways to sort data and it play nice with STL.

Another problem with your code if that it make little sense to have a class circle with a diameter that derives from a class potentialCircle with a radius. Your code will be hard to maintain because it is hard to understand.

You want to store either the diameter or the radius and compute the other one.

unsigned int get_diameter() const { return radius * 2; }

Member like alternative_center make no sense. A circle has only one center. If your class does not respect basic expectations, it will make the code hard to maintain as nobody would known that a circle has 2 centers including you in 3 months!

In a case like yours, it make make sense to add public accessors.

class potentialCircle
{
public:
    unsigned int get_radius() const { return radius; }
....
};

That way, you can still make data private (or sometime protected) while having read only access to it. That way, you can write you comparison function as you wish. And in practice, if you have a class that represent a circle, you usually want at least being able to get basic properties like radius, aread, bounding rectangle by the way of a function.

Another thing is that public derivation as your (from potentialCircle ) would only make senses if you have other classes that derives from it. However, if this is the case, then how would you compare the other kind of circles?

Notes:

  • With C++ 20, three way comparison would be even better.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM