Welcome, Guest: Register On Nairaland / LOGIN! / Trending / Recent / New
Stats: 3,157,970 members, 7,835,243 topics. Date: Tuesday, 21 May 2024 at 07:31 AM

@ C++ Gurus - Programming - Nairaland

Nairaland Forum / Science/Technology / Programming / @ C++ Gurus (1181 Views)

C++ Gurus Get In Here Lets Dissect C++. C++ A_z Tutorials. / VB.NET Assistance Needed From VB.NET Gurus / "extended Mapi" Challenge For C++ Gurus (2) (3) (4)

(1) (Reply) (Go Down)

@ C++ Gurus by gameaddict(m): 4:34pm On Sep 27, 2010
I'm trying to learn some advanced areas of c++ (pointers, data structures etc) and trying to come up with things but I'm finding something very difficult. Is it possible to create a class parenting other classes that automatically, at run time, finds created instances of its children without me explicitly calling it to do so each time I create the child instances?
Re: @ C++ Gurus by Nobody: 2:24am On Sep 28, 2010
Re: @ C++ Gurus by gameaddict(m): 12:02pm On Sep 28, 2010
Thanks. Here's an illustration. Supposing I create a class called 'stuffs' whose instances could be shoe, phone etc i.e

class Stuff;

instances:

Stuff shoe;

Stuff phone; etc

Then I create a class called Box with class Stuff as a child class. Box has a member function that will operate on the Stuff instances.

Is it possible to use some kind of container like a vector in the Box class (maybe in it's constructor) to automatically find all the instances of Stuff i.e shoe and phone that I've created without me explicitly making a call to Box each time I create a Stuff instance like book?

That way, I just concentrate on creating as many stuffs as I want and Box will find them at runtime and operate on them.
Re: @ C++ Gurus by IbrahimB: 2:44pm On Sep 28, 2010
I guess you can do so, although it's not really clear what you want to achieve?

class Stuff
{
protected:
   static vector<Stuff*> stuffs;
}

class Box: public Stuff
{
  //create method to access "stuffs"
}


Anytime you create a new instance of the Stuff class, just update "stuffs". Just note though, that if the instance of the Stuff class goes out of scope, then the stored pointer will be invalid!
Re: @ C++ Gurus by gameaddict(m): 8:28pm On Sep 28, 2010
The main problem is creating the member function in Box to find and access each instance of Stuff on it's own. In PHP, when spidering for links or getting rss feeds, you get an array and loop through it. Something like: foreach($Stuff as stuff) . I can create an array of classes and do it but I want things to be sort of automated. That way, the user just creates as many stuffs as he wants and doesn't have to call Box each time to act on the stuff. and the member function in Box collects them in a vector or something.
Re: @ C++ Gurus by Kobojunkie: 9:39pm On Sep 28, 2010
Why don't you write your code in such a way that everytime the stuff_type constructor is called successfully, each stuff registers itself with the appropriate collection in the Box class?
Re: @ C++ Gurus by IbrahimB: 10:43pm On Sep 28, 2010
gameaddict:

The main problem is creating the member function in Box to find and access each instance of Stuff on it's own.

It shouldn't be a problem. In the example provided, 'stuffs' was declared static so that it is independent of any instance of the Stuff class. It was protected so that it's accessible to the Box class.

All you need to do is to create a member method for Stuff to update 'stuffs' anytime you create an instance of the Stuff class. 'stuffs' is automatically available to the Box class.
Re: @ C++ Gurus by gameaddict(m): 11:29pm On Sep 28, 2010
Thanks guys, nice idea. I'll work on it. So all I have to do is let the user input objects and it's characteristics and a member function, preferably the constructor calls the appropriate overloaded function in Box to register the object so it knows what type of work to do on the object. Won't this change my class relationships? Maybe the change is actually better. The classes only need to be able to communicate at the necessary levels. Maybe I can make a registration function in Box to add each object to a container and then operate on them at run time

pseudo:

Stuff n93(smartphone, phone, flip);
Stuff CODMW(game, disk, PC_Game) etc

Stuff::Stuff(classification, type, extras)
{
registerWithBox(classification, type) overloaded function
}

register with box increments a counter, uses it as a subscript and adds it to a container. Maybe this will work.
Re: @ C++ Gurus by IbrahimB: 12:05am On Sep 29, 2010
gameaddict:
Maybe this will work.

You'll have to try out to know. wink

What do you really need an overloaded function for?

Is inheritance the best relationship to use? It seems composition and not inheritance is what you really need. If "Stuff is a kind of Box" does not sound right, then it's better you do away with inheritance.

If Box is just to store stuffs, just create a vector of stuffs member, right within the Box class. Then create an "add" function for adding Stuff objects to the container.

Good luck.
Re: @ C++ Gurus by tomX1(m): 6:38am On Sep 29, 2010
On Microsoft platforms (Visual C++) you can use the CObject array. It's is a dynamic array that is specialy designed for storing objects and you do not have to define a size for it on creation.

Read up on it, it may serve your purpose.
Re: @ C++ Gurus by tomX1(m): 6:39am On Sep 29, 2010
On Microsoft platforms (Visual C++) you can use the CObject array. It's is a dynamic array that is specialy designed for storing objects and you do not have to define a size for it on creation.

Read up on it, it may serve your purpose.
Re: @ C++ Gurus by gameaddict(m): 8:28am On Sep 29, 2010
@ IbrahimB: Stuff is not meant to be a kind of box. Box is actually a separate class that performs operations on each instance of stuff I create. That is why I wanted to make stuff a member of Box in Box's constructor. I need an overloaded registration function in the mix because different stuffs need to be attended to in different ways. Phones will be arranged and packaged as expensive items, kept where they won't break while a stuff instances like shoe can be kept anywhere.
Re: @ C++ Gurus by IbrahimB: 3:23pm On Sep 29, 2010
@Gameaddict

gameaddict:

Then I create a class called Box with  class Stuff as a child class.

It is very important to make proper use of terminologies. When you say child class, you are referring to inheritance. A child class inherits from another class (i.e. the parent class). That was why I brought the whole issue of Stuff being a kind of Box or not. The proper term to use in your case is member class.

Secondly, the issue of overloaded functions. If you're creating only one single function for registering stuffs, then overloaded function wouldn't be the right term to use.
Re: @ C++ Gurus by gameaddict(m): 7:46pm On Sep 29, 2010
You're right about the first one. The registration function is actually more than one though I only put one there. Thanks, you guys have been very helpful.
Re: @ C++ Gurus by Kobojunkie: 8:36pm On Sep 29, 2010
pseudo:

Static class Box
{
property:
ICollection stuffcollection

. . . . .
function AddStuff(Stuff a)
{
. . . .
stuffcollection.Add(a)
}

}



Stuff n93(smartphone, phone, flip);
Stuff CODMW(game, disk, PC_Game) etc

Stuff::Stuff(classification, type, extras)
{
registerWithBox(classification, type) overloaded function OR Box.AddStuff(this)
}



this way, you can, through the box class keep access to all instances of the stuff class created.
Re: @ C++ Gurus by gameaddict(m): 9:34pm On Sep 29, 2010
Thanks. grin grin grin
Re: @ C++ Gurus by gameaddict(m): 3:08pm On Oct 02, 2010
Wow, I finally did it. Had a lot of problems with circular headers and correct ways of passing addresses to the vector containing object pointers.

Here's the code:

Obj.h //the object header

Obj.h :

#ifndef OBJECT_H
#define OBJECT_h
#include <iostream>
#include <string>
#include <vector>
#include "Box.h"

class Obj
{
friend class Box;
public:
Obj(std::string obj_name, Box &box) //pass the box as well so it knows what to register itself with
{
name = obj_name;
box.registerObject(this);

}
std::string giveAttributes()
{
return name;
}
private:
std::string name;

};


#endif


///////////////////////////////////////////////////////////////////////////

Box.h :

#ifndef BOX_H
#define BOX_H

#include <iostream>
#include <vector>
#include <string>

class Obj; //tell it about the object class here, but don't include the header file for Obj. It will be included in Box.cpp


class Box
{
public:
Box();
void registerObject(Obj *obj);
void outPutAll();
private:
//static int counter; decided not to use this variable
std::vector<Obj *> Objects; //the list of objects go into this box

};


#endif


///////////////////////////////////////////////////////////////////////////////////////


Box.cpp :

#include "Box.h"
#include "Obj.h" //compiler complains of incomplete type when trying to use pointers to objects if this isn't included. It defines the object structures


Box::Box()
{
}

void Box::registerObject(Obj *obj)
{

// i wanted to use a counter to get list of objects but I had subscript out of range errors
//Objects[counter] = &obj this generates subscript out of range errors, had to use push_back()

Objects.push_back(obj);

//counter++; did not implement this since i could use vector.size()
}

void Box::outPutAll()
{
std::cout <<Objects.size() << " items in Box \n";
for(unsigned int i = 0; i < Objects.size(); i++) //why does <= generate an error?
{
std::cout << Objects[i]->giveAttributes() <<"\n";
}

}


/////////////////////////////////////////////////////////////////////////////////////////////////////////


Finally main.cpp :

#include "Box.h"
#include "Obj.h"


int main()
{
Box myBox; //first create a box
Obj Chair("Couch", myBox); // name of object and tell it which box it goes into
Obj Table("dining Table", myBox); //o yeah, dining table can't go into a box? who says? grin
Obj Book("Eco 101", myBox);
myBox.outPutAll();
std::cin.get();
return 0;

}



////////////////////////////////////////////////////////////////////////////


Thanks guys. grin grin grin grin grin grin
Re: @ C++ Gurus by IbrahimB: 3:44pm On Oct 02, 2010
Nice one!

As regards your question:
why does <= generate an error?

Remember that arrays (and vectors) in C++ are zero-indexed. So for an array of size = 10, the only valid indices are array[0] to array[9]. So your index always has to be < the size; obviously <= will generate an error.

Secondly, you have to be careful when dealing with pointers, as they can become invalid at anytime! A useful addition to your code would be:

if(Objects[i] != NULL)
{
   std::cout << Objects[i]->giveAttributes() <<"\n";
}

Or better still, you could decide to store copies of the objects themselves rather than their addresses. This makes sense since the objects are not so "heavy". You would then need copy constructors and assignment operators for that.

Lastly, you can consider returning and passing your strings by reference rather than by value. It is faster as no copying is involved.

std::string giveAttributes()
now becomes std::string& giveAttributes().

Cheers.
Re: @ C++ Gurus by gameaddict(m): 8:17pm On Oct 02, 2010
Thanks. grin
Re: @ C++ Gurus by Derenle: 2:46pm On Apr 16, 2011
Write a C++ program to roll 3 dice,it would show the values of these dice, and show the total value of these dice. Can someone help me?
Re: @ C++ Gurus by selencious(f): 6:53pm On Apr 16, 2011
Is the program asking the user to roll the dice or it automatically rolls the 3 dice and gives u random output. If its automatic, then this is the program.

#include <iostream>
#include <time.h> //you must add this to use time(NULL)
#include <cstdlib>
using namespace std;
int main()
{

int dice1;
int dice2;
int dice3;
{time_t now,begin;

cout<< "\nRolling the First Dice" << endl;
srand((unsigned)time(NULL)); // initialize the random number generator

dice1 = rand() % 6 + 1; //remainder of the random number divided by 6
now = begin = time(NULL); while (now<=begin+2){now=time(NULL);} //waits 2 seconds
cout<< "\nRolling the Second Dice" << endl;
srand((unsigned)time(NULL)); /*you should reinitialize the random number each time or you'll end up with the same number on each dice*/
dice2 = rand() % 6 + 1;
now = begin = time(NULL); while (now<=begin+2){now=time(NULL);} //waits 2 seconds
cout<< "\nRolling the Third Dice" << endl;
srand((unsigned)time(NULL));
dice3 = rand() % 6 + 1;
now = begin = time(NULL); while (now<=begin+2){now=time(NULL);} //waits 2 seconds
}
int Total;
cout<< "\nYou just rolled " << endl << dice1 << endl << endl << dice2 << endl << endl << dice3 << endl << endl;
Total=dice1+dice2+dice3;
cout<< "\nThe total of these dice is " << Total << endl << endl;

//Display my name
cout << "Programmer: Selencious\n" << endl;

return 0;
}

(1) (Reply)

If You Are Thinking Of Picking Computer Programming As A Career / Programmer Vs Developer / A Simple Point Of Sale System For Sale. Good For BUSINESS

(Go Up)

Sections: politics (1) business autos (1) jobs (1) career education (1) romance computers phones travel sports fashion health
religion celebs tv-movies music-radio literature webmasters programming techmarket

Links: (1) (2) (3) (4) (5) (6) (7) (8) (9) (10)

Nairaland - Copyright © 2005 - 2024 Oluwaseun Osewa. All rights reserved. See How To Advertise. 51
Disclaimer: Every Nairaland member is solely responsible for anything that he/she posts or uploads on Nairaland.