Non static members as default parameters in C++ - c++

I'm refactoring a large amount of code where I have to add an extra parameter to a number of functions, which will always have a value of a member of that object. Something like
class MyClass
{
public:
CMyObject A,B;
void MyFunc(CMyObject &Object);
// used to be void MyFunc();
};
Now, I'd actually like it to read
class MyClass
{
public:
CMyObject A,B;
void MyFunc(CMyObject &Object = A);
};
But I'm not allowed to have a default parameter that is a non-static member. I've read this similar question which suggest this isn't possible, but I'm wondering if there is any reasonable workaround. Reason being that 95% of the time the default parameter will be used, and thus using a default parameter would hugely reduce the amount of code I have to change. My best solution so far is something like this;
class MyClass
{
public:
CMyObject A,B;
void MyFunc(BOOL IsA = TRUE);
};
void MyClass::MyFunc(BOOL IsA)
{
CMyObject &Object = A;
if (!IsA)
Object = &B;
}
This is less than elgant, but is there a better way of doing this that I'm missing?
Edit: FWIW, the reason for the extra parameter is to externalize some state related members from the object in question to aid multi-threading.

How about :
class MyClass
{
public:
CMyObject A,B;
void MyFunc()
{
MyFunc(A);
}
void MyFunc(CMyObject &Object);
};
?

Another way:
class MyClass
{
public:
MyObject A,B;
void MyFunc(MyObject MyClass::*myObject = &MyClass::A) {
MyObject& obj = *(this->*myObject);
}
};
This makes it even impossible to pass in an MyObject member from another MyClass instance. Your three valid options to call MyFunc are .MyFunc(), .MyFunc(&MyClass::A) and .MyFunc(&MyClass::B)

Related

Can I make a variable _const from now on_?

I'm using a library that has a class with an init function distinct from its constructor. Every time I make a new instance I need to call, for example:
MyClass a;
a.init();
Since init is not const, this prevents me from creating const instances (I can't write const MyClass a). Is there some way to call init and then declare from "here on out" (I guess for the remainder of the scope) my variable is const?
This works, but relies on not touching the original variable:
MyClass dont_touch;
dont_touch.init();
const MyClass & a = dont_touch;
If you're using C++11 you could use a lambda function
const MyClass ConstantVal = []{
MyClass a;
a.init();
return a;
}();
This allows you to keep the initialization in place while never giving outside access to the mutable object.
see also:
http://herbsutter.com/2013/04/05/complex-initialization-for-a-const-variable/
You can create a wrapper class and use that instead.
If MyClass has a virtual destructor you can feel safe deriving from it like this:
class WrapperClass : public MyClass
{
public:
WrapperClass()
{
init(); // Let's hope this function doesn't throw
}
};
Or write a class that contains the MyClass instance
class WrapperClass
{
public:
WrapperClass()
{
m_myClass.init(); // Let's hope this function doesn't throw
}
operator MyClass&() {return m_myClass;}
operator const MyClass&() const {return m_myClass;}
private:
MyClass m_myClass;
};
Or write a template to solve this general problem using one of the two solutions above: eg.
template <class T> class WrapperClass : public T
{
public:
WrapperClass()
{
T::init();
}
};
typedef WrapperClass<MyClass> WrapperClass;
Create a function that wraps the first two lines and gives you an object that is ready to go.
MyClass makeMyClass()
{
MyClass a;
a.init();
return a;
}
// Now you can construct a const object or non-const object.
const MyClass a = makeMyClass();
MyClass b = makeMyClass();
Update
Using makeMyClass() involves construction and destruction of a temporary object everytime the function is called. If that becomes a significant cost, makeMyClass() can be altered to:
MyClass const& makeMyClass()
{
static bool inited = false;
static MyClass a;
if ( !inited )
{
inited = true;
a.init();
}
return a;
}
It's usage, as described earlier, will continue to work. In addition, once can also do this:
const MyClass& c = makeMyClass();
You can actually do it quite simply, even without C++11 and lambdas:
const MyClass a;
{
MyClass _a;
_a.init();
std::swap(const_cast<MyClass&>(a), _a);
}
The use of const_cast is admittedly a bit of a hack, but it won't break anything as const is quite a weak specifier. At the same time, it is quite efficient, as the MyClass object is only swapped, not copied (most reasonable expensive-to-copy objects should provide a swap function and inject an overload of std::swap).
Without the cast, it would require a helper:
struct Construct_Init {
operator MyClass() const
{
MyClass a;
a.init();
return a;
}
};
const MyClass a = Construct_Init();
This can be like this in a function (the Construct_Init structure needs not be declared at namespace scope), but it is a bit longer. The copy of the object may or may not be optimized away using copy elision.
Note that in both cases, the return value of init() is lost. If it returns a boolean where true is success and false is failure, it is better to:
if(!a.init())
throw std::runtime_error("MyClass init failed");
Or just make sure to handle the errors appropriately.

how to set internals of a class

Hi I am pretty new to C++ and im converting C code to C++. I started by converting all the structs to classes, and added accessors and mutators for the internals, but some structs have other structs inside them. I want to know the best method for setting the internals of a class within a class, such as
struct1.struct2.struct3.i = 5;
where i is an int. Should I be passing as reference using accessors? but seeing as accessors tend to be const would this be something I should do?
something like
class1.get_class2().get_class3().set_i(5) or something if it can be done in this kind of format.
This is probably a dumb question but i have no idea how to do it, Thank You
class1.get_class2().get_class3().set_i(5)
is possible if get_class2() is non-const and returns a non-const pointer reference.
However, this approach completely breaks the encapsulation. The users of class1 should not (and must not) know that class1 uses class2 inside and that in turn uses class3 inside.
If a setter-API is absolutely necessary, then a better approach is do it hierarchically. For example
// User
class1.set_i( 5 );
// class1
class1::set_i( int x ) { class2_obj.set_i( x ); }
// class2
class2::set_i( int x ) { class3_obj.set_i( x ); }
// class3
class3::set_i( int x ) { i_ = x; }
I am not so sure about that ... did you put a class inside a class or an object inside a class ?
something like :
class OBJ1
{
//methods , and other stuff
}
class OBJ2
{
public OBJ1 *O ;
}
is valid , so you can acces a method like :
OBJ2 *N2 ;
N2->O->some_method();
however , something like
class OBJ2
{
class OBJ1;
}
is not valid :P
again... not sure if this is exactly what you asked ...
If you really have a good reason to access your member object via getters and setters, you can do the following:
class A {
public:
void f() const {}
};
class B {
public:
const A &get_a() const {
// the returned reference will be read-only, i.e. only non-const member
// functions can be called, and public members can not be written.
// it needs to be stored in a const A & object.
return a;
}
A &get_writable_a() {
return a;
}
void set_a(A &a) {
//make sure that the assignment operator of A will take care of all the
//dirty internals, such as internal buffers that need to be deleted.
this->a = a;
}
private:
//the member
A a;
};
int main() {
B b;
b.get_a().f();
}
If you don't have a good reason to do so, I'd recommend to simply make it a public member, and access it directy:
class A {
public:
void f() const {}
};
class B {
public:
A a;
};
int main() {
B b;
b.a.f();
}
Isn't that simply much more elegant?
Note that you can use friend to specify other functions or classes that are allowed to directly access your private members.
As was also pointed out in an other answer, in most cases it is a bad idea to make a member object visible to the outside at all.

Add commands to the instance manager with association to public method of two clases

I want to be able to add commands to the manager instance and associate those commands with invoking public methods from both class A and class B when they're executed. I know that in order to achieve this the class Command should have a pointer to a class member function instead of a regular function (void (T::*Handler)() instead of void(*Handler)() ), but I found myself lost in how exactly I can achieve this. I have the following code:
typedef void (*Handler)();
class Command {
public:
Command(char*, Handler);
private:
char* name;
Handler handler;
};
class CommandManager {
public:
CommandManager();
void addCommand(Command*);
void execute(char* commandName);
private:
Command** commands;
}
// implementation, copy constructor and destructor should be ignored at this point since they do
// not affect directly the question I'm trying to find an answer for.
I have another two classes. Let's say they're class A and class B, both having methods with return type void
and with no params. I also have class C which contains member variables of type pointers to A and B:
class C {
public:
// some public stuff here
private:
A* a;
B* b;
CommandManager* manager;
}
Note: It might be easier to introduce inheritance and abstract class but this is something I am limitted not to use(do not ask why :) ), so is there any way to do what I want?
The "best" solution:
typedef std::function<void()> Handler;
//std::function<void()> is the magic bit you were asking about
class Command {
public:
Command(const std::string& name, Handler) {}
private:
std::string name;
Handler handler;
};
class CommandManager {
public:
CommandManager();
void addCommand(std::unique_ptr<Command>);
void execute(const std::string& commandName);
private:
std::vector<Command> commands;
};
and then functionoids go like this
struct A {
void operator()() {std::cout << "A";}
};
Command ACommand = {"A", A()};
//constructs a temporary A,
//then a temporary std::function<void()> is constructed which stores the A
//then the Command stores this function.
struct B {
void named_function() {std::cout << "B";}
};
B bobj;
Command BCommand = {"B", std::bind(&B::named_function, &bobj)};
//bind constructs a functionoid binding the bobj as the "this" of the member function
//then a temporary std::function<void()> is constructed which stores the functionoid
//then the Command stores this function.
The problem is the this pointer passed implicitly to every member function. This makes the signature of the functions of A different from those of B.
Without using templates and inheritance, the easiest way would be to declare the functions of A and B as static. Then, there is no this pointer, and the functions can be assigned to the function pointer handler.
Because it's not likely to be powerful enough, here another way, but I must say it's a kludge, it would really be better to use inheritance.
Define
typedef Handler void (*Handler)(void *);
and implement the static command handlers as follows
void A::doit(void *arg)
{
A *newthis = (A*)arg;
newthis->UseMembersOfA();
}

How to pass a linc to class function and call it?

So I have a class like
class mySafeData
{
public:
void Set( int i )
{
myMutex.lock();
myData = i;
myMutex.unlock();
}
void Get( int& i)
{
myMutex.lock();
i = myData;
myMutex.unlock();
}
private:
int myData;
boost::mutex myMutex;
};
its instance is running. Lets call instance A. I want to create a new class that would take as a start up argument some kind of link to Getter from A and would be capable to somehow save link to thet getter for calling it inside its private methods vhen needed. how to do such thing?
Sounds like you want something like this:
class myOtherData
{
public:
myOtherData(mySafeData& dataSource) :
myDataSource(&dataSource)
{}
private:
// note that if you take the advice in the comments,
// you don't need this wrapper function at all,
// it's simple just to call myDataSource.Get()
int GetData()
{
int result;
myDataSource.Get(result);
return result;
}
mySafeData* myDataSource;
};
mySafeData a;
myOtherData b(a);
// b uses a as its data source (make sure it lives as long!)
I'm not sure what you mean by linc/link. Are you asking for anything more than this pattern?
class Foo {
public:
Foo(mySafeData& d) : data(d) {}
int someFunction() {
int i;
data.get(i);
return i;
}
private:
mySafeData& data;
};
...
Foo f(a);
What's wrong with pointers? Smart, Shared, Scoped... I'll use standard pointers for now.
class B
{
public:
B(mySafeData* ptr) // constructor takes a memory pointer as parameter
:SafeData_ptr(ptr)
{
SafeData_ptr->foo(); // call public function from class A
}
~B() // destructor
{
}
private:
mySafeData* SafeData_ptr; // will hold the mem address of instance A when
// this class is initialized
};
Later on your code, when you have instance A ready, you would do something like this:
B b_demo(&A); // &A passes the memory address of the instantiated object
// and A::foo() will be automatically called when B is constructed.
This is probably not the smartest way to do it, but I think it illustrates the idea.

Data structure that can hold multiple types of data

Like the title says, I'm looking for some kind of data structure which will allow me to store any type of class into it that I need at the time. For example:
Foo *foo = new Foo();
Bar *bar = new Bar();
someContainer.push_back( foo );
someContainer.push_back( bar );
someContainer.access( 0 )->doFooStuff();
someContainer.access( 1 )->doBarStuff();
Ideally, as I showed there, it would also allow me to access the contents and use their functions/etc.
I want one of these as I am attempting to create an "invisible" memory management system that just requires a class to inherit my memory manager class, and everything will work automagically.
Here is an example of what I want the code to look like:
template< class T >
class MemoryManaged
{
MemoryManaged()
{
container.push_back( this );
}
void *operator new()
{
// new would probably be overloaded for reference counting etc.
}
void operator delete( void *object )
{
// delete would most definitely overloaded
}
T &operator=( T &other )
{
// = overloaded for reference counting and pointer management
}
static SomeContainer container;
}
class SomeClass : public MemoryManaged< SomeClass >
{
// some kind of stuff for the class to work
};
class AnotherClass : public MemoryManaged< AnotherClass >
{
// more stuff!
};
I hope that my code helps make clear what exactly it is I want to do. If someone knows some kind of already-built data structure that would allow me to do this, that would be awesome. Otherwise, I am currently working on building some kind of shambling zombie of a linked list class that uses templated nodes in order to link any type of class to any other type of class. I still have no idea how I'd get it to work yet, and I would love to be spared the blood, sweat, and tears (and hair) it would take to figure out how to make it work.
Have a common base class for all of your multiple types. Have the data structure hold onto pointers of your base class's type.
Take a look at boost::any and boost::variant.
Would some hybrid of template specialization and double-dispatch help? Something like this:
class IContainable;
class Operation
{
public:
template<class ElementType> void Process(ElementType* pEl) {
// default is an unrecognized type, so do nothing
}
};
class IContainable
{
public:
virtual void OperateOn(Operation* pOperation) = 0;
};
class Foo : public IContainable
{
public:
int GetFooCount() { return 1; }
virtual void OperateOn(Operation* pOperation);
};
// specialization of the operation for Foo's
template <> void Operation::Process<Foo>(Foo* pFoo)
{
std::cout << pFoo->GetFooCount() << std::endl;
}
void Foo::OperateOn(Operation* pOperation)
{
pOperation->Process(this);
}
int main()
{
typedef std::vector<IContainable*> ElementVector;
ElementVector elements;
// configure elements;
Operation oper;
for(ElementVector::iterator it = elements.begin();
it != elements.end(); it++)
{
(*it)->OperateOn(&oper);
}
}
If the list of types in the container isn't known at compile time of the operations of the elements on the container, or they are distributed across modules that are not compiled together, then you could instead use dynamic_cast. You'd define a "IFooHandler" class witha pure virtual method called "HandleFoo" that takes a foo pointer. You'd make Operation::Process virtual and have your operation class derive from both Operation and IFooHandler and implement the operation in HandleFoo(). Your Foo::OperateOn method would dynamic_cast(pOperation) and if the result was non-null, it would call HandleFoo() on the IFooHandler pointer you get from the dynamic cast. Otherwise you'd call the generic Operation::Process and it would have some non-type-specific behavior.
Using a std::vector<T*> should work. Indeed, a new class will be created for each instantiation of MemoryManaged. This means that MemoryManaged<Foo> and MemoryManaged<Bar> will be totally different types. Consequently, the static member container will not be common to these two classes. It will be as if you had the two following classes:
class MemoryManagedFoo
{
MemoryManagedFoo()
{
//Here, you know that 'this' is a Foo*
container.push_back(this); //ok, we add 'this' to a container of Foo*
}
static std::vector<Foo*> container;
};
class MemoryManagedBar
{
MemoryManagedBar()
{
//Here, you know that 'this' is a Bar*
container.push_back(this); //ok, we add 'this' to a container of Bar*
}
static std::vector<Bar*> container;
};
As you can see, the static member is not shared by the two instantiations.
Of course, this solution assumes that MemoryManaged will always be used using CRTP, as you described in your question. In other word, this code will work:
class Foo : public MemoryManaged<Foo> { };
but not this one:
class Foo : public MemoryManaged<Bar>
{
// Here, 'container' is a 'vector<Bar*>' and 'this' is a Foo * --> problem
};