I have a class hierarchy in which the base class is abstract. Each derived class has a set of private members which describe parameters that control how the class processes data. I want to enforce implementation of a setParams() function across all derived classes. However, because the parameters for each derived class are unique in number and type to that class, it doesn't seem like creating a pure virtual function will work due to the argument missmatch. Here is an outline of my hierarchy:

class Base{
    public:    
    // Constructor, destructor, etc...
    virtual void setParams() = 0;  // This is the function for I wish to enforce implemenation
}

class DerivedA{
    private:
        int param0;
        double param1;
        char param2;
    public:
    // Internals
  
    // I know this won't work
    virtual void setParams( int param0, double param1, char param2 );
}

class DerivedB{
    private:
        double param0;
        double param1;
    public:
    // Internals
  
    // I know this won't work
    virtual void setParams( double param0, double param1 );
}

I would like to avoid passing parameters in numerical arrays, if possible, because I would prefer the argumets of the setParams function to be descriptive for each class ( mostly for intellisense style lookup ).

Does anyone know if such a construct exists in the c++ spec, and if so, how can I do this?

Thanks

Recommended Answers

All 2 Replies

This seems to be the age old 'artificial' problem that your classes are (at least in part) fundamentally unrelated to each another, but regardless of that they have an established relationship anyway; i.e, your classes do not share a common interface - the fact that they each have a function called setParams is irrelevent, because those functions have nothing in common with each other. I get the feeling that inheritance is maybe the underlying cause of your problem rather than part of the solution.

do you have any more concrete examples of what the real classes actually are? You might be able to build in a different kind of relationship, perhaps by splitting out the data processing/behaviour elements which maybe are related, and the data elements into separate classes.

This seems to be the age old 'artificial' problem that your classes are (at least in part) fundamentally unrelated to each another, but regardless of that they have an established relationship anyway; i.e, your classes do not share a common interface - the fact that they each have a function called setParams is irrelevent, because those functions have nothing in common with each other. I get the feeling that inheritance is maybe the underlying cause of your problem rather than part of the solution.

do you have any more concrete examples of what the real classes actually are? You might be able to build in a different kind of relationship, perhaps by splitting out the data processing/behaviour elements which maybe are related, and the data elements into separate classes.

The classes are absolutely related to each other both in structure and functionality. The classes are all object detectors, and each uses a different algorithm in order to identify specific objects within an input image. The function prototypes for each class are identical, with a single exception being one constructor and the setParams function:

class DerivedDetector : public Detector{
public:
    DerivedDetector();
    DerivedDetector( const std::string& fileName );
    DerivedDetector( /* some list of params unique to each class*/ );
    void setParams( /* some list of params unique to each class*/ );
    virtual ~DerivedDetector();
    virtual void prepare();
    virtual int search( cv::Mat src, const cv::Size& minSize, const cv::Size& maxSize, std::vector<cv::Rect>& detections );
    virtual bool isValid();
    virtual bool read( CvFileStorage* fs, CvFileNode* node );
    virtual bool write( CvFileStorage* fs, CvFileNode* node ) const;
};

Additionally, once a detector is loaded from file or explicitly defined by setting its parameters, a reference to it is appended to a linear container ( vector usually ) of other detectors. So, given a single image, one may step through the list of detectors accumulating the results (cv::Rect) in a single container (vector) by making a single function call:

vector<cv::Rect> detections;
cv::Mat src;  // This is an image region extracted from a large image on the HD
cv::Size minSize;  // this is explicitly set somewhere else.
cv::Size maxSize;  // this is explicitly set somewhere else.
int detectionCount = 0;
for( unsinged int i=0; i<detectors.size(); i++ )
    detectionCount += detectors[i]->search( src, minSize, maxSize, detections );

So, you see, the class hierarchy is not artificial. The classes are fundamentally related to each other via their common interface. The internal algorithms that allow each class to perform its function are fundamentally different, and require different parameters for initialization. Furthermore, the means by which the classes are employed in the overall application demonstrates a homogeneity in both structure and function.

The issue at hand is that I am not the only developer writing these detectors. I am designing the class structure and a few of the detectors. I want to enforce ( explicitly in the code ) an implementation of a setParams() function. However, because each class has different kinds of parameters, I cannot use the virtual keyword for this function. This is not the only function common to all the sibling classes, but it is an important one. Of course, I can tell the other developers that they should include this function. Still, it would be very nice to force its use ( for the case of stubborn collaborators ).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.