About class in C++? - c++

#include <iostream>
using namespace std;
class MyStaticClass{
public:
static int value;
MyStaticClass(){
value++;
}
~MyStaticClass(){}
};
int MyStaticClass::value;
void main(){
MyStaticClass::value = 0;
for (int i = 0; i<9; i++)
MyStaticClass *c = new MyStaticClass();
cout << MyStaticClass::value;
system("pause");
}
Please explain me why the result is 9, and when replace MyStaticClass *c = new MyStaticClass() with MyStaticClass c() the result changes to 0? Finally what is the meaning of int MyStaticClass::value;, why when i delete that line the compiler shows error? Thanks everyone!

The line int MyStaticClass::value; tells the compiler to reserve storage for the static variable value. If you don't do that then the linker will fail.
The result is 9 since the for loop body executes 9 times: you are creating 9 new instances of MyStaticClass (which isn't really a static class, it just has a static member). Note that you ought to delete all these objects else your program leaks memory.
MyStaticClass c(); declares a function prototype for a function c that takes no parameters and returns a MyStaticClass: it does not create an object. This is nicknamed the most vexing parse. Since no object is created, value stays at 0. It would have been a different matter had you written MyStaticClass c;

Related

Accessing specific objects using pointer to multiple arrays of pointers

EDIT: Pasting portion of code that is giving me this issue. Although in my effort to cleanup some of the comments before pasting it here I ended up with a different error. Still happens in the same place though: "munmap_chunk(): invalid pointer
Aborted (core dumped)".
Learning C++; working on polymorphism.
I created a virtual base class and the idea is to have multiple child classes, although I'm currently just stuck on one. My program cannot use vectors, and must include a lambda, so I thought one way to incorporate it would be to just have a function that loops through all my objects and sends the object to the lambda which simply displays the name.
My issue is that I'm trying to figure out how to write the function and lambda parameters/arguments so that it accepts and can work with all my objects. I thought using the base class to create an array of pointers would e the answer but it's resulting in a segmentation fault.
Perhaps I'm misunderstanding inheritance, or perhaps unclear about the way I should be using the pointers and looping through the arrays?
#include <iostream>
#include <string>
#include <cstdlib>
#include <iomanip>
using namespace std;
//Hokeemon Class parent to Child class(es)
class Hokeemon {
friend ostream &operator<< (ostream &stream, Hokeemon &critter);
public:
// int hat, eyes, mouth, health = 0, boredom = 0; string name;//bool alive;
string name;
// virtual string changeName(string); // offers user to change critter name
// virtual void passTime(){health--; boredom++;};
// virtual void description(){};
virtual string getName(){return name;};
};
class Playful : public Hokeemon{ //inherits from parent Hokeemon
public:
Playful() {
cout << "Hokeemon's being hatched.\n";
name = "Test";
}
~Playful(){cout << "Hookemon deleted" << endl;};
};
void forEach(int objects, Hokeemon** ptr, int**, void(*func)(Hokeemon &critter));
int main() {
int obj = 1, aliveSize = 3; int playSize;
srand((time(NULL)));// seed for random numbers
playSize = aliveSize;
int* arraySizes[obj]{}; //to hold sizes of child class arrays
Hokeemon* hPtr[obj];
hPtr[0] = new Playful[playSize]; arraySizes[0] = &playSize; //creates pointer to array of pointers for objects of class Playful
forEach(obj, hPtr, arraySizes, [](Hokeemon &critter){ cout << critter.getName();}); //<< endl; critter.description();});
delete hPtr[0];
return 0;
}
void forEach(int obj, Hokeemon **hArray, int** array, void(*func)(Hokeemon &critter)){
Hokeemon* temp = NULL; //create pointer to hold pointers in array
for( int i = 0; i < obj; i++){ //this level loops through objects in array
temp = hArray[i]; //assigns temp pointer to applicable class pointer
for (int j = 0; j < *array[i]; j++){// loops through objects in class
func(temp[j]);
}
}
}
I can't get it to print past the first object (ptr[0][0] if I'm understanding correctly). I've tried manually printing ptr[0][1] and I get a segmentation fault. How should I be doing it so that I can access the second object of the Child class? Again, I'd like to keep it general so that I can easily add in another Child class and just change the array slightly.

Constructor not getting called

I am making an array of 4 std::list. But when I try to access the array's first list's first A object and call the callMe() method on it I get a weird output.
Now 2 things could have happened:
Either the list was empty.
An A object was created when I tried to access the first element of the first list((*(arrayOflistOfA[0].begin()))).
Details of the above cases:
If no A object was created then I should have got an exception. But I didn't get any exception so I am assuming that an A object was created.
So if an A object was indeed created, then the constructor should have been called.
What am I missing?
#include <iostream>
using namespace std;
class A {
public:
A() {
cout<<"Constructor called"<<endl;
x=20;
}
void callMe();
private:
int x;
};
void A::callMe() {
cout<<"Value of x = "<<x<<endl;
}
int main() {
const int size = 4;
list<A>* arrayOflistOfA = new list<A>[size];
(*(arrayOflistOfA[0].begin())).callMe();
}
The output is:
Value of x = 0
but the output should have been:
Constructor called
Value of x = 20
If no A object was created then I should have got an exception.
Not true.
But I didn't get any exception so I am assuming that an A object was created.
Don't assume. Find out. Go to some documentation for begin() and for iterators and discover that you do not get an exception, you get UB.
An A object was created when I tried to access the first element of the first list((*(arrayOflistOfA[0].begin()))). [And] if an A object was indeed created, then the constructor should have been called.
That's right. Clearly you have no elements in the list.
And we know that, because there is no code in your program that adds elements to the list.
Also you should not dynamically allocate containers unless you really, really need to (I've never found a need to).
You aren't actually populating the list with any values. I tested the below code and include a commented explanation.
#include <iostream>
#include <list>
using namespace std;
class A {
public:
A();
void callMe();
private:
int x = 0;
};
A::A()
{
cout << "Constructor called" << endl;
x = 20;
}
void A::callMe() {
cout << "Value of x = " << x << endl;
}
int main() {
const int size = 4;
list<A>* arrayOflistOfA = new list<A>[size];
cout << arrayOflistOfA->size() << endl; // As you can see, size is 0 here - you created a list of nulls.
for (int i = 0; i < size; i++)
{
arrayOflistOfA->push_back(A());
}
// The below code demonstrates how to loop through the array once it's populated.
list<A>::iterator it;
for (auto& a : *arrayOflistOfA)
{
a.callMe();
}
return 0;
}
I got the answer to my question. Firstly I tried to run this code on my mac with GNU C++ compiler but when I ran the same code on an iPhone simulator it crashed. So as #PaulMcKenzie mentioned, I was indeed trying to dereference an invalid iterator.

Pointer Array outputting integer variables without issue, but strings are all empty

I am a C++ novice and have an assignment using Oldie McOldSchool arrays and pointers. I have looked at this specific problem for about 8-12 cumulative hours now, kind of want to shove my face into a brick wall and don't really know what to think at this point. I am hoping from help from the experts here at SO!
I have the following class
#include <iostream>
#include <string>
using namespace std;
#include "mainclass.h"
#include "mysubobject1.h"
const string dataString[] =
{
"stringvalue,stringvalue,stringvalue,stringvalue,19,51,36,41,STUFF1",
"stringvalue,stringvalue,stringvalue,stringvalue,19,52,37,44,STUFF2",
"stringvalue,stringvalue,stringvalue,stringvalue,19,53,38,46,STUFF3",
"stringvalue,stringvalue,stringvalue,stringvalue,19,54,39,49,STUFF1",
"stringvalue,stringvalue,stringvalue,stringvalue,19,55,30,38,STUFF2",
};
MyObject* myObjectArray[5];
const string* dataArray[5];
int delimiterPositionArray[5][9];
string tokenArray[5][9];
Stuff stuff;
void main()
{
MainClass* mainClass = new MainClass();
dataArray[0] = &dataString[0];
dataArray[1] = &dataString[1];
dataArray[2] = &dataString[2];
dataArray[3] = &dataString[3];
dataArray[4] = &dataString[4];
/*Parse the contents of string into Token array. I have this working and can share if necessary but trimmed it out to keep this easy to look at */
for (int i = 0; i < 5; i++)
{
/* Logic to set the value of stuff goes here - it's very simple and trimmed for ease of reading */
mainClass->add(tokenArray[i][0], tokenArray[i][1], tokenArray[i][2], tokenArray[i][3], stoi(tokenArray[i][4]), stoi(tokenArray[i][5]), stoi(tokenArray[i][6]), stoi(tokenArray[i][7]), stuff);
}
cout << "TEST" << endl;
cout << mainClass->myObjectArray[0] << endl;
}
void MainClass::add(string string1, string string2, string string3, string string4, int int1, int int2, int int3, int int4, Stuff stuff)
{
MyObject myObject;
if (stuff == STUFF2) {
MySubObject1 myObject;
myObject.SetStuff(stuff);
}
myObject.SetString1(string1);
myObject.SetString2(string2);
myObject.SetString3(string3);
myObject.SetString4(string4);
myObject.SetInt1(int1);
int* intArray[] = { &int2, &int3, &int4 };
myObject.SetIntArray(intArray);
//Awful temporary array filling logic (which doent work properly, but works for the purpose of testing this problem)
if (myObjectArray[0] == nullptr)
{
myObjectArray[0] = &myObject;
}
else
{
if (myObjectArray[1] == nullptr)
{
myObjectArray[1] = &myObject;
}
/* ….until the array is filled */ }
}
And the question:
When I inspect this line of code from the main method in the mainclass.cpp in the VB debugger, all looks perfect. Token array contains what I expect:
mainClass->add(tokenArray[i][0], tokenArray[i][1], tokenArray[i][2], tokenArray[i][3], stoi(tokenArray[i][4]), stoi(tokenArray[i][5]), stoi(tokenArray[i][6]), stoi(tokenArray[i][7]), stuff);
I keep stepping through the code and get through the end of the add method. I see that everything looks fine by the time I reach the end of the add method. The strings and integers all appear to get set perfectly. I inspect the following line after the debugger runs over it and see everything looks great. Each array field has the data I expect in it. (the logic sucks and the data is the same for each array index, but that is for a later troubleshooting session :D)
myObjectArray[0] = &myObject;
After the add method runs, execution is deferred back to the main method and the following code outputs the results to the screen:
cout << "TEST" << endl;
cout << mainClass->myObjectArray[0] << endl;
This is where the problem is.... mainClass->myObjectArray[0] has empty values in all string properties and nothing is outputted for them (they contain "").... but the int properties have the proper output for some reason!
If anyone would have any insight into why the ints are available and the strings don't appear to be, I would be eternally grateful!
Thanks again!
Given you really didn't post all of your code, the code you did post shows one major issue, and could be the reason why your program behaves as it does.
In your MainClass::add() function, you're storing the addresses of local variables in the MainClass::myObjectArray array, and attempting to access these addresses from outside the add() function.
A synopsis of the code:
int main()
{
MainClass* mainClass = new MainClass();
//...
mainClass->add(...);
//...
cout << mainClass->myObjectArray[0] << endl; // <-- index 0 points to a garbage value
}
void MainClass::add(string string1, string string2, string string3, string string4, int int1, int int2, int int3, int int4, Stuff stuff)
{
MyObject myObject;
if (stuff == STUFF2) {
MySubObject1 myObject; // <-- Local variable
//...
int* intArray[] = { &int2, &int3, &int4 }; // <-- Another local variable
//...
myObject.SetIntArray(intArray); // <-- Storing address of local
//...
myObjectArray[0] = &myObject; // <-- Storing address of local
//...
}
When add() returns, those addresses will not be pointing to valid variables, since those variables no longer are valid since they are local variables.
So the fix is that you have to ensure that whatever pointers you place in your myObjectArray array, the lifetimes (scope) of those variables that are pointed to will last as long as myObjectArray.
A better solution to use an array of a type that stores "any" value such as an array of std::any.
In addition to this, you should attempt to reduce the unnecessary calls to new. For example, your main function starts off on the wrong foot:
int main()
{
MainClass* mainClass = new MainClass();
This could have simply been:
int main()
{
MainClass mainClass;

Issue with struct constructor causing stack overflow

Both sections of code below are drastically simplified, isolated versions of my actual code. The examples are just big enough to reproduce the problem. The first section of code below works fine. The section section is an attempt to begin to make it part of a class. I'm trying to take tiny steps since small modifications to something like the struct shown below require lots of changes throughout the code which is full of pointers, pointer to pointers and references which all involve this struct. Can you tell me why the second section of code throws a stack overflow within it's constructor and what small changes can be made to fix it?
Working code:
#include <cstdio>
#include <cstdlib>
#include <iostream>
using std::cout;
using std::endl;
const int maxSize = 3;
struct Item{
int count;
Item *items[maxSize + 1];
};
void foo()
{
Item *p;
p = new Item();
p->count = 2;
cout << p->count << endl;
}
int main(int argc, char *argv[])
{
foo();
return 0;
}
Attempt to very gradually modify the code as a whole toward becoming a class:
#include <cstdio>
#include <cstdlib>
#include <iostream>
using std::cout;
using std::endl;
int maxSize = 3;
struct Item{
int count;
Item *items;
Item()
{
items = new Item[maxSize + 1]; // stack overflow
}
};
void Initialize(int size)
{
maxSize = size;
}
void foo()
{
Item *p;
p = new Item();
p->count = 2;
cout << p->count << endl;
}
int main(int argc, char *argv[])
{
Initialize(5);
foo();
return 0;
}
The first call to construct a Item calls new Item[maxSize+1], which calls the default constructor, which calls new Item[maxSize+1], which calls the default construct, and so on until you reach stack overflow.
All the answers are right. I want to suggest a solution for you:
Instead of initializing the array within the ctor, you could implement an initialization method like
init(int maxSize) {
items = new Item[maxSize + 1];
}
that you can call after having constructed the object. This should avoid the stack overflow. In general, you should avoid to place instances of an object inside the object itself. Its better to use Collections of the Item
List<Item>, std::vector<Item>, ...
It is because in working version you have reference to an array of object, but not actual object of Items. In second version, you are creating objects by using keyword new. So, in second version in constructor it will call itself! It will call it's own constructor infinite times. Hence, you see runtime exception stackoverflow :)
Above posters are right. Within the constructor of Item you create items (by creating an array). So the ctor is again called, which creates more items, which .... This is more or less an infinite loop which eats up your stack.
Either stick with the references or use a collection like List - so you can add the items later on dynamically.

C++: save variable value for next call of the function

Is there a way to initialize a variable in a function and save its value for next call of function?
I'm making application in qt and i have one function connected with a signal. I want an variable in that function to change after the other one reaches its goal. Here is the body of that function:
void objekt::advance(int phase)
{
if(!phase) return;
QPointF location = this->pos();
if (int(location.x())==200 || int(location.x())==-200)
{
smijer=-smijer;
}
setPos(mapToParent(smijer,0));
}
I defined the smijer variable as static int. But i dont'know how to initialize it only once, when program starts, and how to keep its new value after each call of the function.
Your answer is in your question basically. Static variables (either a class member or local variable of a function) is initialized only once where it is terminated. For example;
#include <iostream>
int foo () {
static int sVar = 5;
sVar++;
return sVar;
}
using namespace std;
int main () {
int iter = 0;
do {
cout << "Svar :" foo() << endl;
iter++;
}while (iter < 3);
}
if you write a program like that it will print out Svar values just like;
Svar :6
Svar :7
Svar :8
So as you see although we call foo function three times the initialization of a static varible is done only once.
Why am I being downvoted? He wants to change a variable and preserve the states after function calls. (He doesn't specify whether the variable is a member of the class or anything, so I'm assuming it's not. I'll change my answer if he clarifies and states his question less ambiguously.)
You're going about this wrong. To keep a variable after a function's scope ends, you have to allocate it on the heap rather than the stack. You can use new or malloc to do this, but you also have to free this memory with delete and free, in that order.
With new and delete:
#include <iostream>
void modify(int * p){
(*p)++;
}
int main(void){
int * pointer = new int;
*pointer = 5;
std::cout << *pointer << std::endl;
modify(pointer);
std::cout << *pointer << std::endl;
delete pointer;
return 0;
}
And with malloc and free:
#include <iostream>
#include <cstdlib>
void modify(int * p){
(*p)++;
}
int main(void){
int * pointer = (int*)malloc(sizeof(int)); //DO NOT CAST IN C
*pointer = 5;
std::cout << *pointer << std::endl;
modify(pointer);
std::cout << *pointer << std::endl;
free(pointer);
return 0;
}
new does provide facilities for deleting arrays quickly and is better overall for normal use C++.
If smijer is a member of class objekt, then do it like this:
objekt.h:
class objekt
{
...
static int smijer;
...
};
objekt.cpp
int objekt::smijer = YOUR_INITIALIZATION_VALUE;
On the other hand, if you want/need smijer to be a global variable, then do it like this:
globals.h:
extern int smijer;
globals.cpp //Or another .cpp file
int smijer = YOUR_INITIALIZATION_VALUE;
Although in this case I'd stick it in a namespace. In this case it isn't declared static but it does have the lifetime of your program.
Declare the variable as static inside the function and the valued will be remembered. You don't need to initialize it. But you can if you want to.