Calling default constructor instead of overloaded with default parameter - c++

I need a class like that:
class MyClass
{
MyClass()
{
}
public:
MyClass(signed = 0)
{
}
}
I'm wondering if it's possible to call these constructors selectively. Actually what I need is to have two versions of constructors. One to create object with default value like second constructor in my example and the other one to create a default/raw/uninitialized object without any parameters which is used internally in the same class.
I can do following to get over this problem:
class MyClass
{
MyClass(float)
{
}
public:
MyClass(signed = 0)
{
}
}
And to call the first constructor inside my class but it's weird to have unused parameter.

You have a few options. Your "work-around" isn't crazy, and in fact it's a pattern that is encouraged in some circumstances. But consider the named-constructor idiom instead: If you need to create an uninitialized object in a member function of the same class, then create a named private c'tor that achieves this for you:
class MyClass {
public:
MyClass(float f = 0.) : value_{f} {}
private:
float value_;
void g();
MyClass invalid()
{
return MyClass{std::numeric_limits<float>::max()}; }
};
That way, inside of MyClass::g(), you can do:
void MyClass::g()
{
auto newObj = invalid(); // call named c'tor
newObj.value_ = 3.14159;
std::swap(newObj, *this) // swap current object with 'newObj'
// or whatever.
}

Related

Pass class object instance as parameter to another class object instance from main()

I'm having issue on passing class object instance as parameter to another class object instance from main() function. Basically the problem is inside code below:
#include <something>
#include "another_thing"
class A
{
void method1()
{
;
}
void method2()
{
;
}
};
class B
{
// Define an object of type class A
A class_object;
// Constructor
B(A &passed_object)
{
class_object = passed_object;
//other stuff here
}
void method1()
{
;
}
void method2()
{
;
}
};
int main()
{
A firstObject;
B secondObject(firstObject);
// Do something that changes A attributes;
return 0;
}
The problem is that during main()'s execution some attributes of firstObject is changed but within passed_object inside class B I don't see this changes.
EDIT
Based on #HolyBlackCat tips, solved in this way:
Modified A class_object; in A &class_object;, removed class_object = passed_object; from constructor and changed constructor's B(A &passed_object){} in B(A &passed_object) : class_object(passed_object){}
Since the parameter of B() is a reference, simply passing firstObject to it indeed doesn't make a copy.
But you didn't make A class_object; a reference. When you assign to it in B(), you're making a copy.
You need to make the class field a reference: A &class_object;.
And since you have to initialize a reference with an object it should refer to, you're forced to use member initializer list:
B(A &passed_object) : class_object(passed_object) {}

Use object parameter or no parameters for functions?

When creating a function for a class, should the parameter take a pointer to the class type and be invoked using 'this', or create a parameterless function and call it normally. Here is a demonstration:
class ExampleOne {
ExampleOne::ExampleOne() {
performAction(this);
}
void ExampleOne::performAction(ExampleOne *obj)
{
// Do something
}
}
class ExampleTwo {
ExampleTwo::ExampleTwo() {
performAction();
}
void ExampleTwo::performAction()
{
// Do something
}
}
In ExampleOne, the class functions are called with a pointer reference to itself. In ExampleTwo, functions are called without parameters.
I have seen both methods used in c++ code, and do not know which is the correct programming method.
The same question applies to working with the global instance variables, like this:
class ExampleThree {
ExampleThree::ExampleThree() {
Object *obj = new Object;
someFunction(obj);
}
ExampleThree::someFunction(Object *obj) {
// Do something
}
}
Or do we work with the instance variables rather than pointers to it:
class ExampleFour {
ExampleFour::ExampleFour() {
Object *obj = new Object;
someFunction();
}
ExampleFour::someFunction() {
// Do something with Obj instance
}
}
The reason this is done is code reuse, when some work done in the constructor can be used in other functions, if it can't then you should not make a separate function. And you shouldn't make the reuse function before there is a need.
The C++03 way
A {
A() {
Common(42);
}
A(int a) {
Common(a);
}
void Common(int c) {
... do something really complicated with c
}
}
The C++11 way
A {
A() : A(42) { // you can now call other constructors.
}
A(int a) {
... do something really complicated with c
}
}
Also in C++11 the move constructor and move assignment function mostly shares the same code (the latter has a return also) which could be reused.
The preferred way is to do everything in the initializer list for the constructor, which makes everything more safe. And only do something in the body if really needed.
C {
int dc;
C(int c) : dc(c) {
}
}
When you write something like this
MyClass myObject;
myObject.someFunction();
myObject is implicitly passed by reference to MyClass::someFunction, so you can access its attributes or methods by their names, without using the keyword this.
The usual way to use this is when you actually need a pointer or a reference to your object. For example, it is common when you overload operator=() to make it return a reference to the object with return *this;

C++ Child class inheriting parent class constructor

I have an assignment that requires two classes to be derived from a base class. I am having issues getting the derived classes to call the base class constructor and successfully set the inherited variables. I recreated the issue with a dummy program for simplicity since the assignment is much longer.
#include <iostream>
class ParentClass {
public:
ParentClass(int theField1, int junk);
ParentClass() {}
virtual void printField();
virtual void setField(int nf);
protected:
int field1;
};
class ChildClass : public ParentClass {
public:
ChildClass(int theField1);
void printField();
void setField(int nf);
};
ParentClass::ParentClass(int theField1, int junk) {
field1 = theField1;
}
ChildClass::ChildClass(int theField1) {
ParentClass::ParentClass(theField1, 3);
}
void ParentClass::printField() {
std::cout << "The field = " << field1 << std::endl;
}
void ChildClass::printField() {
ParentClass::printField();
std::cout << "Some other stuff." << std::endl;
}
void ParentClass::setField(int nf) {
field1 = nf;
}
void ChildClass::setField(int nf) {
ParentClass::setField(nf);
}
int main() {
ChildClass* myChild = new ChildClass(777);
ChildClass child2(888);
myChild->printField();
child2.printField();
myChild->setField(10);
myChild->printField();
child2.setField(20);
child2.printField();
return 0;
}
Running this gives me the following output:
The field = 0
Some other stuff.
The field = 4197296
Some other stuff.
The field = 10
Some other stuff.
The field = 20
Some other stuff.
Why do the first two attempts not work? Calling the constructor should be initializing the variables to the value passed as a parameter, but they are not actually set until I specifically call a mutator function. I tried a third class which used the parent mutator function in its constructor rather than the parent constructor:
class StepChild : public ParentClass {
public:
StepChild(int nf);
};
StepChild::StepChild(int nf) {
ParentClass::setField(nf);
}
The object as defined in main:
StepChild* step = new StepChild(30);
step->printField();
The output:
The field = 30
Where am I going wrong that attempting to use the parent constructor is not properly initializing these variables?
I also tried changing the parent class to be not virtual, and it worked as well, so it doesn't appear to be an issue with the parent class.
Use initialiser lists:
ParentClass::ParentClass(int theField1, int junk)
: field1(theField1)
{ }
ChildClass::ChildClass(int theField1)
: ParentClass(theField1, 3)
{ }
The following - from your code - creates a temporary ParentClass object and throws it away - that has no affect on the ChildClass object under construction:
ParentClass::ParentClass(theField1, 3); // temporary
If you make the parameters match, you can also do it the c++11 way by putting
using ParentClass::ParentClass( int, int );
in your ChildClass class definition. It is the same as invoking the parent constructor from the ChildClass constructor initialiser list, but a little less esoteric.
Not sure but I find something wrong in the way you are calling base class constructor.
try this way to call base class constructor and see if the problem is solved.

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");
}

class inheritance call a different constructor

hei i have a c++03 class with a simple constructor that take an integer. And a derived class with serialization methods that should take a filename as a constructor, load the integer from it, and then call the first constructor.
class A {
public:
A(int foo);
}
and a derived class:
class XmlableA : public A {
public:
XmlableA(int foo);
XmlableA(string xmlfilename) {
//load foo from xml
// call A::A(foo)
}
}
i tried some different solution but every time i get
no matching function for call to ‘A::A()’
Almost all answers are same, so I would suggest a different solution, which I would prefer personally.
Define a static member function Create as:
class XmlableA : public A {
public:
XmlableA(int foo);
//static member function
static XmlableA Create(string const & xmlfilename)
{
//load foo from xml
int foo = /*load from file*/;
return XmlableA(foo);
}
};
Usage:
XmlableA xmlable = XmlableA::Create(xmlFile);
Initialize it, like so:
XmlableA(int foo) : A(foo) {}
You may also consider:
private:
static int LoadXML(const string& xmlfilename) {
int ret = ...; << load here
return ret;
}
public:
XmlableA(string xmlfilename) : A(LoadXML(xmlfilename)) {
}
In C++ the Base class is constructed BEFORE the Child class, so you will not be able to do this. You could make a Factory that takes a filename and creates an object based on what is in that file.
Example:
class XmltableAFactory {
public:
static XmltableAFactory build(string xmlfilename) {
// read int foo from xmlfilename
return XmltableAFactory(foo);
}
};
And then call it like so:
XmltableA myObj = XmltableAFactory::build(filename);
There are a few things to note.
This means that you will not need the string xmlfilename cosntructor in the XmltableA class because as discussed above, you cannot know foo before the base class's constructor is called.
You can either choose to return from the factory by value or by pointer. The compiler might optimize the return by value because you are creating the object and returning it on the same line. However, return by pointer is usually known to be faster, but you'll have to create a new object and then make sure to delete it when you're done with it.
If you don't want to muck about with memory, take a look at boost's auto_ptr and shared_ptr.
If you want to do something before the call to A::A(int), you end up having to hack, something like
int XmlableA::f(string filename) { /* load foo from xml */; return foo; }
XmlableA(string xmlfilename) : A(f(filename)) {}
OK, so the first one is easy:
XmlableA::XmlableA(int foo) : A(foo)
{
}
The second one requires doing something like
XmlableA(string xmlfilename) : A(fooFromXML(xmlfilename))
{
}
which we can implement as
class XmlableA : public A
{
static int fooFromXML(string filename);
public:
// ...
Note that fooFromXML, which loads the XML file and returns the integer you need, must be static, because when we call it we don't yet have an XmlableA instance to invoke it on.
For multiple arguments (and as a general design), the factory is probably best: if you're wedded to the constructor model and don't care about efficiency, you can do:
class XmlableA : public A
{
static int intFromXML(char const *varname, string const &filename);
public:
XmlableA(string const &xmlfilename)
: A(intFromXML("foo", xmlfilename), intFromXML("bar", xmlfilename))
{
}
if you're concerned about parsing the XML file repeatedly, and don't care about re-entrancy, you can "memoize" xFromXML by having it cache state in a static member.
If your class A does not have a default constructor you have to explicitly call a constructor in the initialization list of your derived class. XmlableA(string fn) : A(readIntegerFromFile(fn)) {}.
However, you should think about "outsourcing" the serialization into a separate class. E.g. what would happen if you have an object of type A and now you want to serialize it? You couldn't because you can only serialize a XmlableA. Furthermore, what would happen if your client decides that he no longer wants a XML serialization but Yaml or some proprietary format? You would have to change all your code.