mali
mali

Reputation: 11

sharing default parameter value in interface class and derived classes in c++

I want to use float value (defaultColour) as a default parameter, in both interface class and Derived class. So how should I define that float defaultColour[] .?

//Interface class
static float defaultColour[]={0,0,0,0}; //This become error

class Interface{
    virtual void print_color(float *color = defaultColour)=0;
}

//Use Interface  Derived.h 
class Derived : public Interface{
    void print_color(float *a = defaultColour);
}

//Derived.cpp 
void Derived :: print_color(float *a){
    //some code using color a[]
}

Upvotes: 0

Views: 223

Answers (3)

mali
mali

Reputation: 11

OK.Thanks every one. I solved with this way. Are there any bad rules?

//Interface class
    class Interface{
        public:
        virtual void print_color(const float *color = defaultColour)=0;
        protected:
        static const float defaultColour[4];
    }

    //Use Interface  Derived.h 
    class Derived : public Interface{
        void print_color(const float *a = defaultColour);
    }

    //Derived.cpp 
    Interface::defaultColour[]={0,0,0,0};
    void Derived :: print_color(const float *a){
            //some code using color a[]
    }

Upvotes: 0

mindriot
mindriot

Reputation: 5678

The default array value should not actually be a problem. With the syntax errors in your examples sorted out, the following example works fine for me:

#include <iostream>
#include <memory>

static float default_array[] = { 42.0f, 13.0f, 2.0f, 0.0f };

struct Interface
{
  virtual void foo(float *a = default_array) = 0;
};

struct Derived : public Interface
{
  void foo(float *a);
};

// Silly contrived example: output array values until a 0 is hit.  You
// better make sure there actually is a 0 at the end.
void Derived::foo(float *a)
{
  while (*a != 0.0f)
  {
    std::cout << *a << std::endl;
    ++a;
  }
}

int main()
{
  std::unique_ptr<Interface> i(new Derived);
  std::cout << "i->foo():" << std::endl;
  i->foo();
  float other_array[] = { 1.0f, -2.0f, 3.0f, -4.0f, 0.0f };
  std::cout << "i->foo(other_array):" << std::endl;
  i->foo(other_array);
}

Note, however, that defining default_array in the header will violate the One Definition Rule if multiple compilation units include that header. To avoid that, you will have to use @MartinBonner's solution and make the array a static member variable.

If you know that you will call foo() only through a pointer to Interface, then you do not need to re-specify the default value in Derived::foo's declaration. However, if you also expect to do something like this:

  Derived der;
  der.foo();

Then you will run into a problem because Derived::foo() does not actually exist. GCC will complain:

test.cpp: In function ‘int main()’:
test.cpp:37:15: error: no matching function for call to ‘Derived::foo()’
       der.foo();
               ^
test.cpp:37:15: note: candidate is:
test.cpp:18:10: note: virtual void Derived::foo(float*)
     void Derived::foo(float *a)
          ^
test.cpp:18:10: note:   candidate expects 1 argument, 0 provided

A somewhat generic workaround in this case could be to add the following inline function declaration to Derived:

inline void foo() { static_cast<Interface*>(this)->foo(); }

Upvotes: 2

Make defaultColour a const static public member of Interface.

Interface.h

    class Interface{
    public:
        static float defaultColour[colourSize]; // You have got a const for the
                                                // array size somewhere,
                                                // haven't you?

        virtual void print_color(float *color = defaultColour)=0;

    }; // Need trailing ; here

Derived.h

    class Derived : public Interface {  // Need to derive from Interface.
    public:
        void print_color(float *a = defaultColour); // Just declare function here.
    };

Derived.cpp

    void Derived::print_color(float *a){  // define function here.
            //some code using color a[]
    }

Interface.cpp (this may be a new file)

    float Interface::defaultColour[] = {255,255,255,150};

Upvotes: 1

Related Questions