Can I make a variable _const from now on_? - c++

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.

Related

Does C++ have a defined way to pass a pointer to a member function of a member object of a class?

Let's say I have some function:
void myFunction(void (MyClass::*function)(int), MyClass& myClass) {
(myClass.*function)(1);
}
Which is called as follows:
class MyClass {
int value;
void setValue(int value) {
this->value = value;
}
}
MyClass myClass;
myFunction(&MyClass::set_value, myClass);
This function takes the object myClass and says to call its member function setValue, which it calls with the parameter set to 1.
Before I realized C++ had support for passing member functions as as parameters, I had manually set my code to take in a object and function pointer and then determine the offset between their addresses. This offset could then be saved to call the same member function if given a different instance of the same type of object.
But yeah, then I discovered you can just do Class::*function which (I assume) does exactly what I had previously built/described.
Which leads me to my issue, let's say I have the same function as before, except I change my class structure a bit:
class MyClass {
ChildClass childClass;
}
class ChildClass {
int value;
void setValue(int value) {
this->value = value;
}
}
Is there then a way in C++ to pass the setValue function into myFunction given that setValue is now within the ChildClass object within MyClass?
The most obvious solution would be to add a setValue member function to MyClass which calls the setValue function within its childClass object, like so:
class MyClass {
ChildClass childClass;
void setValue(int value) {
this->childClass.setValue(value);
}
}
class ChildClass {
int value;
void setValue(int value) {
this->value = value;
}
}
MyClass myClass;
myFunction(&MyClass::setValue, myClass);
However, due to the semantics of the project I am working on this would not be a desirable solution. Thus, I was curious about whether or not there is a way to achieve this in C++. If not, I can certainly just implement it manually (it would be the same as before, except you would save the offset between the childClass member and MyClass as well as the offset of the setValue member and ChildClass), but naturally I'd like to know if there is a more "built-in" way of achieving this.
Is there then a way in C++ to pass the setValue function into myFunction given that setValue is now within the ChildClass object within MyClass?
There is a way by adding a level of indirection. That level of indirection is polymorphic function wrapper std::function. myFunction can take a std::function argument, which can be initialized with arbitrary accessor functions, including labdas. E.g.:
#include <functional>
struct ChildClass {
int value;
void setValue(int value) {
this->value = value;
}
};
struct MyClass {
ChildClass childClass;
};
void myFunction(std::function<void(MyClass&, int)> const& f, MyClass& myClass) {
f(myClass, 1);
}
int main() {
MyClass myClass;
myFunction([](MyClass& a, int b) { a.childClass.setValue(b); }, myClass);
}
Using std::function your can get rid of MyClass& argument and expect the user to provide the required object inside std::function captured by the lambda expression:
void myFunction2(std::function<void(int)> const& f) {
f(1);
}
int main() {
MyClass myClass;
myFunction2([&myClass](int b) { myClass.childClass.setValue(b); });
}
Note that std::function can store at least sizeof(void(Undefined_class::*member_pointer)()) inside the object without allocating heap memory. The C++ standard doesn't require that, however, it seems that the reason for this optimization is that using std::function for member function pointers is not much worse than using member function pointers directly. Or, in other words, if you replace member and member function pointers in your code with std::function, your application won't be penalised by extra memory allocations for that†. With gcc on x86_64 that results in 16 bytes of inline storage in std::function, which can store a lambda capture object with 2 object references.
† The size of std::function is still larger than that, though, and it is a non-trivial type, so it cannot be passed or returned in registers.
There is a solution with c++17 fold expressions:
#include <iostream>
struct S
{
int foo() {return 1;}
};
struct T
{
S s;
};
template<class ... Args>
int call(T &t, Args... args)
{
return (t .* ... .* args)();
}
int main()
{
T t{};
std::cout << call(t, &T::s, &S::foo);
}
You have to explicitly give the whole "path" to the member function, but I think this is unavoidable (just from a logical point of view). This scales to an arbitrary level of indirection. You can also template also the T and it shouldn't be to bad to add functions arguments.
Does this do what you want?
class ChildClass {
public:
int value;
void setValue(int value) {
this->value = value;
}
} ;
class MyClass {
public:
ChildClass childClass;
} ;
static void myFunction(void (ChildClass::*f)(int), MyClass& myClass) {
(myClass.childClass.*f) (1) ;
}
int main() {
MyClass myClass;
myFunction(&ChildClass::setValue, myClass);
}
Note the semi-colons after the class definitions.

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.

C++ Non-destructible classes

Is there any way in C++ to create class within a function, and then prevent it from destructing?
like
class someclass {
public:
int x;
someclass() { x = 0; };
}
someclass::x;
and then somewhere
someclass * somefunction()
{
someclass somecl ();
return &somecl;
}
So we call function 'somefunction' and get pointer to class for later using. I need it to exist as long as program runs/it destructed by other function. Is there any way to do it without storing it inside arrays or vectors?
I'm not sure if what you're looking for is a way to define an object once and only once, returning a pointer to the same object each time, or to create a factory function that returns the a newly constructed object each time. If it's the second, look at previous answers. If it's the first, check out static variables. As an example, you could write
someclass * somefunction()
{
static someclass somecl ();
return &somecl;
}
This ensures that somecl is only defined once, when the function is initially run and that it will be alive until your program exits. (For a more precise description of the order of cleanup for static variables, see here.)
Yes, you have to allocate the memory on the heap and then delete the memory when you are done.
someclass * somefunction()
{
return new someclass();
}
int main()
{
someclass * myclass = somefunction();
// do stuff with myclass
delete myclass;
return 0;
}
someclass * somefunction()
{
return new somecl ();
}
You were very close :)
You could create it on the heap rather than the stack:
someclass * somefunction()
{
return new someclass();
}
You may also want to consider returning it in a smart pointer, to explicitly transfer ownership and control its lifetime.
I'm not exactly sure what you are driving at, I can imagine two different use cases where you would want to make a class indestructible.
Case 1: Singleton
The idiomatic way to do this, is to use a static instance of the class that's declared within an accessor function:
class Foo {
public:
static Foo& globalFoo();
private:
Foo() {};
~Foo() {};
};
Foo& Foo::globalFoo() {
static Foo myFoo;
return myFoo;
}
int main() {
Foo& myFoo = Foo::globalFoo();
}
That way, it is impossible for other code to either construct or destruct any instance of Foo, it can only use the one instance that's provided by the globalFoo() function.
Case 2: Wrapped allocation/deallocation
If you just want to force allocation/deallocation to happen via certain static functions, you only need to make both the constructor and the destructor private (just as in the singleton case), and add static functions to the interface for allocation/deallocation:
class Foo {
public:
static Foo* makeFoo();
static void destroyFoo(Foo* aFoo);
private:
Foo() {};
~Foo() {};
};
Foo* Foo::makeFoo() {
return new Foo();
}
void Foo::destroyFoo(Foo* aFoo) {
delete aFoo;
}
int main() {
Foo* myFoo = Foo::makeFoo();
Foo::destroyFoo(myFoo);
}

C++ initialization list -- parameter comes from the constructor body itself?

I have some code like that:
#include <string>
class another_foo
{
public:
another_foo(std::string str)
{
// something
}
private:
// something
};
class foo
{
public:
foo();
private:
another_foo obj;
};
foo::foo() : obj(str) // no `: obj("abcde")`, because it is not that simple in real situation.
{
std::string str = "abcde"; // generate a string using some method. Not that simple in real situation.
// do something
}
and I am going to initialize obj which is a private member of foo. But this code does not compile. How can I use the variable in the constructor's body in the initialization list?
AFAIK, the only method is to separate the code generating str from the constructor as another function, and then call that function directly in the initialization list. That is...
#include <string>
class another_foo
{
public:
another_foo(std::string str)
{
// something
}
private:
// something
};
class foo
{
public:
foo();
private:
another_foo obj;
// std::string generate_str() // add this
static std::string generate_str() // EDIT: add `static` to avoid using an invalid member
{
return "abcde"; // generate a string using some method. Not that simple in real situation.
}
};
foo::foo() : obj(generate_str()) // Change here
{
// do something
}
But is there any better method?
Yes, you have to move it to a function. If it's a single-purpose thing (only used for this initialisation) and you have access to C++11 lambdas, you can use a single-purpose lambda. Otherwise, just use a member function like you did. Just be careful about calling virtual functions in there, because the object is still under construction. Best make it static, if possible.
Lambda example:
class foo
{
public:
foo();
private:
another_foo obj;
};
foo::foo() : obj([] { return "abcde"; } ())
{
// do something
}
But is there any better method?
To be short: No, not if you're not willing to change either the way obj is allocated OR it's semantic.
You can do variants of this, like making generate_str() static, or better (if the code is short) using a lambda:
foo::foo() : obj( []{ return "abcde"; }() )
{
}
HOWEVER: If the object construction requires logic which is dependent on other members, then you have to make sure the initialization order of members reflect the inter-dependencies (order them in the declaration from the independant to the dependants) OR BETTER: change the semantic of obj OR allocate it on the heap.
Changing allocation have a cost on construction/destruction and a very minor cost on access, so it's not the best solution most of the time, but it solves the problem:
class foo
{
public:
foo();
private:
std::unique_ptr<another_foo> obj; // no sharing of the instance
};
foo::foo() // obj is null
{
// do something
auto result_obj_info = compute_something();
obj = new another_foo( result_obj_info );
// OR if you use this http://stackoverflow.com/questions/12547983/is-there-a-way-to-write-make-unique-in-vs2012
obj = std::make_unique<another_foo>( result_obj_info );
}
However, I would recommand changing the semantic of another_foo instead so that it have value semantic:
#include <string>
class another_foo
{
public:
another_foo(); // this create an invalid anoter_foo, unusable.
another_foo(std::string str) // this create a valid another_foo
{
// something
}
// make sure copy/move functions are available, either automatically or manually
bool is_valid() const;
private:
// something
};
inline bool is_valid( const another_foo& obj ) { return obj.is_valid(); }
class foo
{
public:
foo();
private:
another_foo obj;
};
foo::foo()
{
assert( is_valid( obj ) == false);
std::string str = "abcde"; // generate a string using some method. Not just simple like that in real situation.
// do something
obj = another_foo( str );
assert( is_valid( obj ) == true);
}
That way your another_foo type acts like a handle for it's resources. If it shouldn't be copied, just make it move-only. Take a look at how std::thread or std::unique_ptr work for example.
The risk when writing a member function that will be called during construction is that you may change it afterwards to use some of the class' data members, which may not have been initialized at the time of the call.
It's probably better to define an external function to generate the string, like this:
namespace {
std::string generate_str()
{
return "abcde";
}
}
foo::foo() : obj(generate_str())
{
// do something
}
That way, if you have to pass parameters to the function, the use of uninitialized data members or virtual member function return values will be visible from the constructor, hence more easy to catch.
If it's a constant specific to that class, you can define it that way:
class foo {
public:
foo();
private:
static const std::string STR;
another_foo obj;
};
const std::string foo::STR = "abcde";
foo::foo() : obj(STR)
{
}
Edit
Since it seems it's not a constant, you may have to use a static member function for this job. (Or a lambda, your choice)
class foo {
static std::string generate_string() const;
};
Implementation:
std::string foo::generate_string() const {
return std::string("abcde");
}

Non static members as default parameters in 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)