Hi all,

I am currently working on a large software project for scientific computing for my PhD research.

I am working on the architecture for part of the project now, and I am struggling with how to working with a polymorphic pointer as a function input parameter, by reference.

The following pseudo-code illustrates what I am trying to achieve:

class BaseClass
{
protected:
    double parameter;
};

class DerivedClass : public BaseClass
{
};

class SecondDerivedClass : public BaseClass
{
};

class AnotherClass
{
public:
    void setParameterOfDerivedClass( BaseClass*& baseClass, double& parameterValue );
};

int main
{

// Create instance of DerivedClass
DerivedClass myDerivedClass;
DerivedClass* pointerToMyDerivedClass;

// Set pointer to derived class to address of myDerivedClass
pointerToMyDerivedClass = &myDerivedClass;

// Create instance of AnotherClass
AnotherClass myAnotherClass;

// Set parameter through AnotherClass, for object of DerivedClass
myAnotherClass.setParameterOfDerivedClass( myDerivedClass, 10.0 );
myAnotherClass.setParameterOfDerivedClass( pointerToMyDerivedClass, 10.0 );

return 0;
};

The issue I am having is that for the function protype for setParameterOfDerivedClass() I want to use a polymorphic pointer to be able to pass objects of DerivedClass and SecondDerivedClass as the first argument of the function. For this I have defined the first argument as being of type BaseClass* and passed this as reference.

The user interface however now requires the function call:

myAnotherClass.setParameterOfDerivedClass( pointerToMyDerivedClass, 10.0 );

However, I want the user interface to be such that the user doesn't have to create a pointer to pass as function argument, but rather just pass the object itself, as:

myAnotherClass.setParameterOfDerivedClass( myDerivedClass, 10.0 );

Can I write my function prototype such that it accepts all derived classes of BaseClass as the first argument, without the user having to pass a pointer to that object?

Another question I have is related to the fact that AnotherClass needs access to the protected member variable parameter in BaseClass. Do I make AnotherClass a friend of BaseClass to achieve this? How do I implement this the best?

If there's a totally different and better way to achieve what I am trying to achieve, I am also open to suggestions.

I guess I can also overload the setParameterOfDerivedClass() for each derived class of base class, but I'm trying to avoid doing that by using the polymorphic pointer.

Any feedback would be greatly appreciated.

Thanks!

Kartik

Not absolutely sure what your trying to accomplish here. Is this what your looking for?

#include <iostream>

class BaseClass
{
protected:
    double parameter;
};

class DerivedClass : public BaseClass
{
};

class SecondDerivedClass : public BaseClass
{
};

class AnotherClass
{
public:
	void setParameterOfDerivedClass( BaseClass * baseClass, double parameterValue ) 
	{
		std::cout<<"called ptr"<<std::endl;
	}
	void setParameterOfDerivedClass( BaseClass & baseClass, double parameterValue ) 
	{
		std::cout<<"called refer"<<std::endl;
	}
};

int main()
{
	DerivedClass myDerivedClass;
	BaseClass* pointerToMyDerivedClass;

	pointerToMyDerivedClass = &myDerivedClass;

	AnotherClass myAnotherClass;

	myAnotherClass.setParameterOfDerivedClass(myDerivedClass, 10.0 );
	myAnotherClass.setParameterOfDerivedClass(pointerToMyDerivedClass, 10.0 );

	return 0;
}

Not absolutely sure what your trying to accomplish here. Is this what your looking for?

#include <iostream>

class BaseClass
{
protected:
    double parameter;
};

class DerivedClass : public BaseClass
{
};

class SecondDerivedClass : public BaseClass
{
};

class AnotherClass
{
public:
	void setParameterOfDerivedClass( BaseClass * baseClass, double parameterValue ) 
	{
		std::cout<<"called ptr"<<std::endl;
	}
	void setParameterOfDerivedClass( BaseClass & baseClass, double parameterValue ) 
	{
		std::cout<<"called refer"<<std::endl;
	}
};

int main()
{
	DerivedClass myDerivedClass;
	BaseClass* pointerToMyDerivedClass;

	pointerToMyDerivedClass = &myDerivedClass;

	AnotherClass myAnotherClass;

	myAnotherClass.setParameterOfDerivedClass(myDerivedClass, 10.0 );
	myAnotherClass.setParameterOfDerivedClass(pointerToMyDerivedClass, 10.0 );

	return 0;
}

No, sorry, to clarify, I want to create a function that can be used as:

myAnotherClass.setParameterOfDerivedClass(myDerivedClass, 10.0 );
myAnotherClass.setParameterOfDerivedClass(mySecondDerivedClass, 10.0 );

What is the function prototype I define in AnotherClass to achieve this, given that both DerivedClass and SecondDerivedClass are derived from BaseClass?

Thanks,

Kartik

So you can't add a virtual function to the base class??
Then your only decision is to make BaseClass completely abstract, i.e a standalone instance is disallowed, or not. If you don't then think about adding the functionality to say class absFunc, which is inherited by BaseClass, then you get compile time check that you are not setting a parameter that cant be set.

Example of virtual function

#include <iostream>
class BaseClass
{
public:
  // IF BaseClass is abstract do this:
  // virtual void setParameter(const double) =0; 
  // BUT it is not [in your example] , so do this:
  virtual void setParameter(const double) {}   // You could put an exception/error etc here.
};

class DerivedClass : public BaseClass
{
  double P1;
public:
  virtual void setParameter(const double D) 
    {
      std::cout<<"P1 Set:"<<D<<std::endl; 
      P1=D;
    }
};

class SecondDerivedClass : public BaseClass
{
double PX;
public:
  virtual void setParameter(const double D) 
  { PX=4.0*D; std::cout<<"PX Set"<<PX<<std::endl;}
};

class AnotherClass {
public:
void setParameterOfDerivedClass( BaseClass * baseClass, double parameterValue )
  {
    std::cout<<"called ptr"<<std::endl;
    if (baseClass)
      baseClass->setParameter(parameterValue);
  }
  
void setParameterOfDerivedClass(BaseClass& baseClass,
                 const double parameterValue) const
{
  std::cout<<"called refer"<<std::endl;
  baseClass.setParameter(parameterValue);
}
  
};

int
main()
{
  AnotherClass A;
  DerivedClass B;
  
  A.setParameterOfDerivedClass(B,10.0);
  A.setParameterOfDerivedClass(*B,30.0);
}

Is this what you are after?? [Sorry if it is not...]

p.s. Note Please make the destructor virtual if you go this route.

So you can't add a virtual function to the base class??
Then your only decision is to make BaseClass completely abstract, i.e a standalone instance is disallowed, or not. If you don't then think about adding the functionality to say class absFunc, which is inherited by BaseClass, then you get compile time check that you are not setting a parameter that cant be set.

Example of virtual function

#include <iostream>
class BaseClass
{
public:
  // IF BaseClass is abstract do this:
  // virtual void setParameter(const double) =0; 
  // BUT it is not [in your example] , so do this:
  virtual void setParameter(const double) {}   // You could put an exception/error etc here.
};

class DerivedClass : public BaseClass
{
  double P1;
public:
  virtual void setParameter(const double D) 
    {
      std::cout<<"P1 Set:"<<D<<std::endl; 
      P1=D;
    }
};

class SecondDerivedClass : public BaseClass
{
double PX;
public:
  virtual void setParameter(const double D) 
  { PX=4.0*D; std::cout<<"PX Set"<<PX<<std::endl;}
};

class AnotherClass {
public:
void setParameterOfDerivedClass( BaseClass * baseClass, double parameterValue )
  {
    std::cout<<"called ptr"<<std::endl;
    if (baseClass)
      baseClass->setParameter(parameterValue);
  }
  
void setParameterOfDerivedClass(BaseClass& baseClass,
                 const double parameterValue) const
{
  std::cout<<"called refer"<<std::endl;
  baseClass.setParameter(parameterValue);
}
  
};

int
main()
{
  AnotherClass A;
  DerivedClass B;
  
  A.setParameterOfDerivedClass(B,10.0);
  A.setParameterOfDerivedClass(*B,30.0);
}

Is this what you are after?? [Sorry if it is not...]

p.s. Note Please make the destructor virtual if you go this route.

Ummmm, I guess this isn't what I meant. The code you presented has the function setParameter() included as a public function in BaseClass and its derived classes, however all I want to do is implement a function in AnotherClass that sets a protected member variable of the derived classes. I want do achieve this by being able to pass objects of both derived classes to the set function in AnotherClass.

So basically, I want to be able to do the following:

// Declare objects
AnotherClass A;
DerivedClass B;
SecondDerivedClass C;

// Call set functions
A.setParameter(B,10.0);
A.setParameter(C,20.0);

I've renamed the setParameterOfDerivedClass() function to setParameter as I think this might be causing confusion. The setParameter() function in AnotherClass needs to be able to accept objects of both DerivedClass and SecondDerivedClass as its first function argument.

I can sorta achieve this with the function prototype:

void AnotherClass::setParameter(BaseClass*& pointerToBaseClass, double& parameter);

The issue with this however is that I can't pass the objects B and C directly as the first argument; I have to pass pointers to them.

I basically want to be able to have a function as follows:

void AnotherClass::setParameter(BaseClass& baseClass, double& parameter);

This however doesn't accept objects B and C as the first argument; it only accepts an object of BaseClass, such as A.

So, to summarize, my question is, how do I write the function prototype for setParameter() such that the first function argument is generalized to be able to pass objects B and C (or objects of any other derived class of BaseClass).

Hope this clarifies what I mean.

Thanks for your input,

Cheers,

Kartik

In which case you cannot do this. Let us break this problem down some more, if you do this :

class A { 
  protected: 
    int var;
};

class B{
  public:
    void func(A& obj) { obj.var=10.0; } // THIS IS not possible 
};

So in class B, you cannot change the private/protected variables of object A. The only way is if class A (or a derived class) gives you access to the variables.
If you have derived classes D1, and D2 (from A) and you CANNOT change A, then you can make classes D1 and D2 inherit from another class BD, which has the virtual public function that allows you to change the protected variable in A. E.g

Original code:
class A { protected: int X; };
class D1 : public A { };
class D2 : public A { };

New code:

class A { protected: int X; };  // We can't touch this
class BA : public A { public : void changeX() { x=20; } };
class D1 : public BA { };
class D2 : public BA  { };

class something { public: void modify(BA* optr) { optr->changeX(); } };

int main()
{
  D1 obj1;
  somthing Sobj;
  Sobj.modify(&obj1);
}

Sorry for simplify your example but it was getting too long winded. Hope this is clear.

In which case you cannot do this. Let us break this problem down some more, if you do this :

class A { 
  protected: 
    int var;
};

class B{
  public:
    void func(A& obj) { obj.var=10.0; } // THIS IS not possible 
};

So in class B, you cannot change the private/protected variables of object A. The only way is if class A (or a derived class) gives you access to the variables.
If you have derived classes D1, and D2 (from A) and you CANNOT change A, then you can make classes D1 and D2 inherit from another class BD, which has the virtual public function that allows you to change the protected variable in A. E.g

Original code:
class A { protected: int X; };
class D1 : public A { };
class D2 : public A { };

New code:

class A { protected: int X; };  // We can't touch this
class BA : public A { public : void changeX() { x=20; } };
class D1 : public BA { };
class D2 : public BA  { };

class something { public: void modify(BA* optr) { optr->changeX(); } };

int main()
{
  D1 obj1;
  somthing Sobj;
  Sobj.modify(&obj1);
}

Sorry for simplify your example but it was getting too long winded. Hope this is clear.

Thanks for your feedback.

I managed to solve my problem. Seems like I wasn't able to communicate what I needed well enough here. My question pertained particularly to the idea of passing polymorphic pointers to functions, and I've now figured out how to deal with them.

Thanks for all your help.

Kartik

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.