Pointers to Class Members into a class with a private constructor - c++

Lets say that I have a class with a private constructor and that class will be used to represent a single object. Lets say that I have some non-static members that I want to access without using the scope resolution operator. I've noticed that I can achieve this by creating a pointer to the class type to do so. I was wondering why can I declare pointers to that class even if the default constructor is private? Here is an example program.
// Example program
#include <iostream>
#include <string>
class OnlyOne{
public:
void Location(){
std::cout<<10<<std::endl;
}
private:
OnlyOne();
};
int main()
{
//does not work Location() is not a static member
//OnlyOne::Location();
// doesn't work because default constructor is private.
//OnlyOne one;
//one.Location();
OnlyOne* two=nullptr;
two->Location();
}
I've been looking online to see if I could find an answer and haven't been able to get what I'm looking for.

When you declare a pointer of some type, that type doesn't have to be constructible. In fact, that type doesn't even have to be complete. So, this line:
OnlyOne* two = nullptr;
is perfectly fine.
Note that this line:
two->Location();
invokes undefined behavior, since there is no object pointed at by two, and so there is no object on which you can call the Location member function.
In fact, since this type is not constructible, two could never point at a valid object. You have to provide a way to construct such an object, either by providing a public constructor, or by having a static member function, that constructs and returns such an object.

You can use singleton pttern to implement classes that have private constructor:
// Example program
#include <iostream>
#include <string>
class OnlyOne{
public:
static OnlyOne* instance() {
static OnlyOne obj;
return &obj;
}
void Location(){
std::cout<<10<<std::endl;
}
private:
OnlyOne() { }
};
int main()
{
//does not work Location() is not a static member
//OnlyOne::Location();
// doesn't work because default constructor is private.
//OnlyOne one;
//one.Location();
OnlyOne* two=OnlyOne::instance();
two->Location();
}

Related

Calling the default constructor on c structs

The code below compiles just fine (unless the call to method is uncommented).
Why is it allowed to "call" to the default constructor? (there shouldn't be one)
Why is the declaration of the member function not an error?
.
extern "C"
{
struct S
{
int some_int;
void method(){}
};
}
int main()
{
S s();
// s.method();
return 0;
}
First, S s(); declares a function named s that takes no arguments and returns an object of type S. Just like int f();.
Second, that extern "C" isn't relevant here. It's used, roughly, for functions that are written in C and called from C++. It doesn't mean "pretend that this code is C code".
Third, S does have a default constructor. The compiler generates one. In this case it doesn't do anything, because there are no members of S that require non-trivial initialization. To use the default constructor you'd write S s; or S s{};.
Fourth, the reason that declaring a member function is okay is that a struct and a class in C++ can have member functions. I know, that sounds tautologous, but it's important to keep in mind that a struct can have member functions, static data, private, protected, and public members just like a class. The only differences between a struct and a class is that by default members of a class are private while members of a struct are public, and by default a base of a class is inherited privately while a base of a struct is inherited publicly.
Adding a default constructor (although it's optional here) and using curly-braces rather than parenthesis or you don't even need to use that, will solve your issue:
....
struct S {
S() {} // declaring the constructor explicitly here
};
....
int main(void) {
S s{}; // Don't use s() - a function, instead, call the
// default constructor
// S s;
s.method();
return 0;
}

How to make a C++ class whose objects can only be dynamically allocated?

The problem is to create a class such that the non-dynamic allocation of object causes compiler error.
For example :
Employee e1; // compiler error
Employee *e3 = new Employee; // works fine
You can do something like this:
#include <memory>
struct S {
static std::unique_ptr<S> create() {
return std::unique_ptr<S>(new S);
}
private:
S() {}
};
int main() {
auto ptr = S::create();
}
Note that using the following doesn't work as expected:
S() = default;
I guess it is due to the fact that the class is treated as an aggregate and thus the following still works for it:
S s{};
Moreover, the following create function does not work in the example above:
static std::unique_ptr<S> create() {
return std::make_unique<S>();
}
That's because make_unique must be able to access the constructor to do its work, but this is not possible for the constructor is private.
You need to make your constructors private and make a factory returning a shared pointer on the object.
Create a private destructor in the class. When you make a private destructor, the compiler would generate a compiler error for non-dynamically allocated objects because compiler need to remove them from stack segment once they are not in use.

What is the proper way to call default constructors?

Lately I have been having difficulties with constructors, and the different attempts from other questions and guides always have some form of segfault waiting for me at runtime (making compiling 80% of my time spent programming).
The following example shows the basic idea on what I am trying to accomplish:
struct Coord3{
float x, y, z;
Coord3() {x=0;y=0;z=0;};///Is this Correct?
};
struct Stat{
int Str,Dex,Int;
Stat(){Str=0;Dex=0;Int=0;};
};
struct Item{
Stat myStats;
Item(){...};
};
class SimpleChar{
public: ///to keep things simple for now
Coord3 pos;
Stat myStats;
int level;
float health;
Item inventory[20];
SimpleChar(){
level=0;
health=100;
}///What happens with 'pos', 'inventory' and 'myStats' in this class's constructor?
};
int main(){
SimpleChar myChar;
if(myChar.inventory[0].get()!=NULL){...}///this caused the most recent SEGFAULT as mentioned below. Why wouldn't this work?
}
With this example I have a bunch of simpler structs (similar to Coord3 and Stat). These structs are at the base level of my "engine", and are used accordingly to make higher level structs, then those are used to make the highest level structs (such as Item being item related information and SimpleChar having generic RPG character statistics, like an inventory and stats). The errors I get are so different according to the situation that it was difficult to keep track them all, but the most interesting one was a SEGFAULT on:
if(itemSet.inventory[a].get()!=NULL); ///Note: this is originally a shared_ptr AND was in a struct known as 'ItemSet', which held all item information
So basically what I ask is:
When are the default constructors invoked?
When the constructors are used, do they also invoke their member's constructors?
What would be the correct way to declare these members both in the classes and main()?
What is the correct way to create the constructor?
EDIT: The code has been spruced up for anyone that is way too obsessed with if the code is "valid by syntax" instead of actually answering the question.
EDIT 2: Since the SEGFAULTs are not created from constructor format then I ask if it is possible to get a SEGFAULT if an instance variable is too large in size? I mainly ask this because recently I have changed a class member to a pointer instead of an object and it worked fine.
when you declear a class like:
class foo{
public:
foo(){} // this is default constructor
};
But if you write:
class foo{};
The compiler will supply a default constructor for you. When you write:
class SimpleChar{
Coord3 pos; // default constructor of Coord3 will be called,
//if you need somrthing else do that in SimpleChar constructor;
Stat myStats; // same
int level;
float health;
Item inventory[20]; // an array will be created that can hold 20 item,
// constructor (default) will be called 20 times
};
Inside main() if you want to initialise an object with default constructor:
className instanceName;
is enough.
When You write:
SimpleChar myChar;
The following constructor is called:
SimpleChar(){
level=0;
health=100;
};
An additional point ; is mandetory after a class or struct definetion, which is absent in struct item{}
And default access specifier of struct is public but in class it is private, Which means you can not create object in main with default constructor.Edit:
"if an instance variable is too large in size" you may get a std::bad_alloc if it is being allocated dynamically in runtime but generally not a segfault. it happens when you access area you do not own.
1: When are the default constructors invoked?
Default constructors are called when:
You create an object without passing parameters
MyClass* myClass = new MyClass(); //<- this is you invoking it.
When you inherit from a class and dont specify a constructor in the initialization list for that base class.
class MyClass: public BaseClass
{
MyClass()
{
}
};
MyClass* myClass = new MyClass(); // <-- this will invoke the default constructor for "MyClass" and "BaseClass".
When you put an object in any stack and dont specify a constructor.
void methodA()
{
MyClass myClass; // <-- this will invoke the default constructor for "MyClass"
}
Same happens if you declare an object as a member of a class in its stack.
class MyClass
{
MyClass()
{
}
DifferentClass m_member;
};
If you dont specify a different constructor for m_member in the initialization list of MyClass, its default constructor will be used.
2: When the constructors are used, do they also invoke their member's
constructors?
As long as they are in the stack and not in the heap, and you dont specify otherwise in the initialization list of the class. Yes.
3: What would be the correct way to declare these members both in the
classes and main()?
It will depend on what you want, if you want to initialize them with its default constructor, you can just declare them as follow:
MyClass myClass; //<- this is fine.
4: What is the correct way to create the constructor?
A good practice is to ALWAYS initialize your members in the initialization list, for example:
struct Stat
{
int Str,Dex,Int;
Stat(): Str(0), Dex(0), Int(0)
{};
};
A simple example of how the default constructor works:
class base
{
int i;
public:
base()
{
i = 10;
cout << "in the constructor" << endl;
}
};
int main()
{
base a;// here is the point of doubt
getch();
}

How to call a derived class method from a base class method within the constructor of base

I am wondering if it is possible to call a derived class´ function from within a function called by the base constructor (shouldn´t it already be created when the code in the brackets are executed?)
#pragma once
class ClassA
{
public:
ClassA(void);
virtual ~ClassA(void);
void Init();
protected:
short m_a;
short m_b;
virtual void SetNumbers(short s);
};
include "ClassA.h"
#include <iostream>
ClassA::ClassA(void) : m_a(0), m_b(0)
{
Init();
}
ClassA::~ClassA(void)
{
}
void ClassA::SetNumbers(short s)
{
std::cout << "In ClassA::SetNumbers()\n";
m_a = s;
m_b = s;
}
void ClassA::Init()
{
this->SetNumbers(2);
}
#pragma once
#include "ClassA.h"
class ClassB : public ClassA
{
public:
ClassB(void);
virtual ~ClassB(void);
virtual void SetNumbers(short);
int x;
};
#include "ClassB.h"
#include <iostream>
ClassB::ClassB(void)
{
}
ClassB::~ClassB(void)
{
}
void ClassB::SetNumbers(short s)
{
std::cout << "In ClassB::SetNumbers()\n";
m_a = ++s;
m_b = s;
ClassA::SetNumbers(s);
}
Any suggestions how to do it?...
Thank You in advance :)...
No. All parts of B (starting with A, as it's base) are constructed before B's constructor is called. So, by the time SetNumbers is called, no part of B (except for the A part) has been constructed --- and that may include the v-table, so there's no way to know where that call is going to go.
Of course, there is a simple solution to this: Call B::SetNumber() from within B's constructor (That is, after all, the purpose of B's constructor)
You can't do this for the simple logical reason that while the base class is being constructed, the derived class hasn't even begun to be constructed. You can't call a member function on an object that doesn't exist (yet).
In practice, even if you managed to call SetNumbers and assign to the member variables of the derived class before they were initialized they would surely be overwritten when they finally get initialized. I admit it's a bit pointless to reason about this as we would be well outside defined behaivour.
No, sorry. :( It might compile in one or two C++ compilers, but it's not recommended. From the C++ FAQ Lite section 10.7:
[10.7] Should you use the this pointer
in the constructor?
[...snip...]
Here is something that never works:
the {body} of a constructor (or a
function called from the constructor)
cannot get down to a derived class by
calling a virtual member function that
is overridden in the derived class. If
your goal was to get to the overridden
function in the derived class, you
won't get what you want. Note that you
won't get to the override in the
derived class independent of how you
call the virtual member function:
explicitly using the this pointer
(e.g., this->method()), implicitly
using the this pointer (e.g.,
method()), or even calling some other
function that calls the virtual member
function on your this object. The
bottom line is this: even if the
caller is constructing an object of a
derived class, during the constructor
of the base class, your object is not
yet of that derived class. You have
been warned.
NOTE: Emphasis mine.
More details at the link
The only time you can do this is when something is derived from a template that is parameterised by itself:
template<typename T> class base
{
T* down_cast() throw()
{
return static_cast<Derived*>(this);
}
const T* down_cast() const throw()
{
return static_cast<const Derived*>(this);
}
public:
base()
{
down_cast()->doSomething();
}
/* … */
};
class derived : private base<derived>
{
public:
void doSomething()
{
}
};
Note that doSomething is public and not virtual.
We can static_cast to derived, because it's known that derived is the derived type.
Deriving something from a base parameterised by itself is a strange thing to be doing at the best of times. It's said that when the ATL team in microsoft used it they asked the C++ compiler team if it was valid and nobody was sure, though it is valid because template construction depends on names as follows:
First the template is available, but not used in a class. Then, the name derived available. Then it instantiates the layout of base<derived> — this requires knowledge of the member variables and virtual functions, as long as none of that depends upon knowledge of derived’s layout (pointers and references are fine) this will all go okay. Then it will create the layout of derived, and finally it will create derived’s member functions, which may include creating member functions for base<derived>. So as long as base<derived> doesn’t contain a derived member variable (base classes can never contain a member variable of a type derived from themselves) or a virtual function that requires knowledge of derived’s layout we can indeed do the dicey-looking piece of inheritance above.
This includes being able to call non-virtual public members of derived from base during construction, because it's already part of base. There are strong limitations on this. In particular, if doSomething() depends on anything constructed in derived's constructor it won't work as derived hasn't been constructed yet.
Now, is this actually a good idea? No.
A simple design solution is to use aggregation instead of inheritance.

Passing "this" to a function from within a constructor?

Can I pass "this" to a function as a pointer, from within the class constructor, and use it to point at the object's members before the constructor returns?
Is it safe to do this, so long as the accessed members are properly initialized before the function call?
As an example:
#include <iostream>
class Stuff
{
public:
static void print_number(void *param)
{
std::cout << reinterpret_cast<Stuff*>(param)->number;
}
int number;
Stuff(int number_)
: number(number_)
{
print_number(this);
}
};
void main() {
Stuff stuff(12345);
}
I thought this wouldn't work, but it seems to. Is this standard behavior, or just undefined behavior going my way?
When you instantiate an object in C++, the code in the constructor is the last thing executed. All other initialization, including superclass initialization, superclass constructor execution, and memory allocation happens beforehand. The code in the constructor is really just to perform additional initialization once the object is constructed. So it is perfectly valid to use a "this" pointer in a class' constructor and assume that it points to a completely constructed object.
Of course, you still need to beware of uninitialized member variables, if you haven't already initialized them in your constructor code.
You can find a good answer to this here (C++ FAQ).
All inherited members and members of the calling class are guaranteed to have been constructed at the start of the constructor's code execution and so can be referenced safely within it.
The main gotcha is that you should not call virtual functions on this. Most times I've tried this it just ends up calling the base class's function, but I believe the standard says the result is undefined.
As a side-note on the presented code, I would instead templatize the void*:
class Stuff
{
public:
template <typename T>
static void print_number(const T& t)
{
std::cout << t.number;
}
int number;
Stuff(int number_)
: number(number_)
{
print_number(*this);
}
};
Then you'd get a compile error if the type of t doesn't have a number member.
Andy, I think you're wrong about the undefined part of the standard.
When you're in the constructor, "this" is a pointer to an object whose type is the base class of the object you're creating, which means that virtual functions partially implemented in the base class will be called and the pointers in the virtual table won't be followed.
More info in the C++ Faq Lite...