• Hey, guest user. Hope you're enjoying NeoGAF! Have you considered registering for an account? Come join us and add your take to the daily discourse.

C++ Help?

Status
Not open for further replies.

Exuro

Member
Yeah, the assignment says that I'm going to read in a file of floating point numbers. So I'd have to do some rounding error checking? Probably going to talk to the professor about this as this is an c++ intro class and this sounds a little too complicated for us beginners.
 
Your implementation is undefined based on the internal precision representation of the machine. If you run in a debugger you can inspect the program like so:

(gdb) p bWidth
$20 = 1.01
(gdb) p bWidth*i
$21 = 9.0899999999999999
(gdb) p bWidth*(i+1)
$22 = 10.1

On my machine I get 0 entries in bin number 9, as you're using < and not <=, or more correctly perhaps, an epsilon test.
 

Exuro

Member
BriareosGAF said:
Your implementation is undefined based on the internal precision representation of the machine. If you run in a debugger you can inspect the program like so:

(gdb) p bWidth
$20 = 1.01
(gdb) p bWidth*i
$21 = 9.0899999999999999
(gdb) p bWidth*(i+1)
$22 = 10.1

On my machine I get 0 entries in bin number 9, as you're using < and not <=, or more correctly perhaps, an epsilon test.
Okay sorry but I'm not quite sure what you're doing here. I can go into the debugger(which I've never used) by typing gdb into the terminal and then from there what exactly do I do? I tried file ./a.out but it just said no debugging symbols found.
 
To compare doubles/floats/decimals, you'd have to do something like subtract one from the other, and comparing the value to an epsilon. Such is the nature of floating point.
 
Exuro said:
Okay sorry but I'm not quite sure what you're doing here. I can go into the debugger(which I've never used) by typing gdb into the terminal and then from there what exactly do I do? I tried file ./a.out but it just said no debugging symbols found.
[michael@namaste tmp] g++ -g -Wall foo.cpp
[michael@namaste tmp] gdb a.out
GNU gdb 6.3.50-20050815 (Apple version gdb-1705) (Fri Jul 1 10:50:06 UTC 2011)
[...]
done

(gdb) b main
Breakpoint 1 at 0x1000016f2: file foo.cpp, line 9.
(gdb) r
Starting program: /private/tmp/a.out
Reading symbols for shared libraries ++......................... done

Breakpoint 1, main (argc=1, argv=0x7fff5fbffc40) at foo.cpp:9
9 int size = 10;
(gdb) b 59 if x == 9 && i == 5
Breakpoint 2 at 0x100001a6e: file foo.cpp, line 59.
(gdb) c
Continuing.
[...]
i = 5

Breakpoint 2, main (argc=1, argv=0x7fff5fbffc40) at foo.cpp:59
59 if (array[x] >= min + bWidth*i && array[x] < min + bWidth*(i+1))
(gdb) p bWidth
$1 = 1.01
(gdb) p bWidth*i
$2 = 5.0499999999999998
(gdb) p bWidth*(i+1)
$3 = 6.0600000000000005
 

Exuro

Member
Thanks guys, I'll be going over this tonight and hopefully will understand what all I need to do to get the program working properly.
 

jokkir

Member
When a class contains this "int number() const" what does it do? I mean, what values are passed to it and the difference between "const int number()"?

Thanks, I kinda suck at this right now >__<
 

Lathentar

Looking for Pants
jokkir said:
When a class contains this "int number() const" what does it do? I mean, what values are passed to it and the difference between "const int number()"?

Thanks, I kinda suck at this right now >__<
Its a member function named "number". Everything to the left of "number" is the return type, so in this case "int" will be returned from the function. Everything in the "()" are the parameters to the function, in this case there are none. The "const" to the right of the "()" indicates that the function does not change any of the class's data when you call the function, usually this indicates the function is an accessor to data.
 

Kalnos

Banned
jokkir said:
When a class contains this "int number() const" what does it do? I mean, what values are passed to it and the difference between "const int number()"?

Thanks, I kinda suck at this right now >__<

I'm somewhat rusty with my C++ but it should just mean that the function is readonly basically. It can't modify the object for which it's called.
 
I can't figure out why this little guy either outputs 0 or some random negative string of numbers.

Code:
int primeCalc (int input, int &remainder)
{
	int count;
	count = input;
		
	if (count > 2 && count <= input)
	{
		remainder = input%count;

		count--;
	}

	cout << remainder <<endl;

	return remainder;
}

Gotta take an input of a number, and determine whether or not it's prime. I for the life of me can't find my mistake.
 
Notrollious said:
I can't figure out why this little guy either outputs 0 or some random negative string of numbers.

Code:
int primeCalc (int input, int &remainder)
{
	int count;
	count = input;
		
	if (count > 2 && count <= input)
	{
		remainder = input%count;

		count--;
	}

	cout << remainder <<endl;

	return remainder;
}

Gotta take an input of a number, and determine whether or not it's prime. I for the life of me can't find my mistake.

What does the debugger tell you the values of count and remainder are as you step through line by line?

Alternatively, cout the values of remainder and count between each line of code and watch how they change.

Also, step through the code with various edge cases. What happens if you pass 0 as the input?
 

maharg

idspispopd
Why are you both taking a reference to a remainder variable and returning the remainder? Drop the reference argument and just return it. I think there's good odds you're holding a reference to something you shouldn't be somewhere.
 
it was accidentally left over from testing, but the same error persists, regardless.

Half-and-Half:

I've already put something in to prevent the input value from being zero, it'll just kick back an error.


I have everything set up but I keep getting 0 for the remainder, no matter what. I think it's something wrong with how I'm setting up my equation.
 

Lathentar

Looking for Pants
Shouldn't it be >= 2?

Actually, what the hell is this function supposed to do?

If the input is 2 or less, you'll output whatever you passed in as remainder as its never set... so that explains your random number. Otherwise, you're doing input % input (which is 0), then decrementing count once.

There are no loops in this function. Usually you need a loop to determine if something is prime.
 

wolfmat

Confirmed Asshole
Edit: The following is completely wrong:

&remainder is the literal address of the variable remainder in memory (something like 0x4F931120). To get the value of remainder, or to change it, you'd have to dereference &remainder (meaning, use the address to access the value). Which is kind of crazy here! You might therefore want to change the signature.

Get rid of "int &remainder" in the signature.

In the first two lines of the function:
Declare remainder as int.
Give it a value of 0.
 

Lathentar

Looking for Pants
wolfmat said:
&remainder is the literal address of the variable remainder in memory (something like 0x4F931120). To get the value of remainder, or to change it, you'd have to dereference &remainder (meaning, use the address to access the value). Which is kind of crazy here! You might therefore want to change the signature.

Get rid of "int &remainder" in the signature.

In the first two lines of the function:
Declare remainder as int.
Give it a value of 0.
None of this is correct.

Back to the problem at hand. Why would a isPrime function return a remainder anyway? What's the remainder from? Don't you just want to return a bool to indicate whether the number is prime or not?
 
So look at the problem like this:

If you pass in 1 as input, what is the value of count here:

Code:
	int count;
	count = input;

Now, plug that value of count into the if-statement and what happens?

Code:
	if (count > 2 && count <= input)

Did it enter the if-statement? If it did, plug count into the code inside of the if-statement. If it did not, what is the value of remainder and why?

edit:
Answer those questions, and you'll have answered some of your questions.
 
Thanks guys. I figured out my problem. The loop was wrong, and I was counting it wrong. The program was to determine whether an entered integer was a prime number or not.

I did need a reference call though, due to how I had my functions set up.

If anyone would like to critique it:

Code:
#include <iostream>
#include <cmath>
using namespace std;

//Function to get the integer from the user.
void getInput (int& input);

//Function that calculates the remainder from the given input.
//Returns: the remainder
int primeCalc (int& input, int& remainder);

//Function to display whether it is a prime number or not.
void displayPrime (int remainder);

int main()
{
	int input = 0, remainder = 0;
	
	//Function calls.
	getInput (input);
	primeCalc(input, remainder);
	displayPrime(remainder);

	return 0;
}
void getInput(int& input)
{
	cout << "Please enter an integer greater than 1: ";
	cin >> input;

	//Preventing the user from entering anything less than or equal to 1.
	if (input <= 1)
	{
		cout <<"You have entered an invalid integer, program terminating." <<endl;
		exit (1);
	}

}
int primeCalc (int& input, int& remainder)
{
	int count;
	count = 2;
			
	do 
	{
		remainder = input%count;
		count++;

	}
	while ((count > 2 && count < input) && remainder != 0);

	return remainder;
}

void displayPrime (int remainder)
{
	if (remainder == 0)
		cout << "The integer is a composite number." <<endl;
	else 
		cout << "The integer is a prime number. " <<endl;
}

First year CS student here. Still learning the ropes of this programming thing. My problems lie with my logic, which doesn't always translate well from brain to computer.
 

Margalis

Banned
Notrollious said:
I have everything set up but I keep getting 0 for the remainder, no matter what. I think it's something wrong with how I'm setting up my equation.

int count;
count = input;

....
remainder = input%count;

So remainder = input%count, and count equals input...

So remainder = count%count.

Yes. That will be zero.

It appears that you wanted a loop someplace and let it out or something...this whole function is kind of gobbledygook.

I strongly suggest you do the following:

#1. Put a comment at the top of the function describing what it takes and what it returns.
#2. Write a comment for yourself that explains how your function is going work
#3. Write the function to match your comments.

By this I mean:

//this function takes an integer and returns a boolean where true indicates primeness


//we will do this by seeing if the number is divisible by 2, by 3, by 4, etc etc, all the way up to 1/2 the number. If it is divisible by none of these it is prime.

Once you've done this the function almost writes itself.

Edit: Now looking at your solution. Comments:

You only need to loop up to 1/2 the number, no integer is divisible by a number that's more than it's half.

Returning the remainder is a little weird. In plain english what is it that this function does? The best way to program (IMO) is to write functions that are very clear in what they do and piece them together. When people run into problems it's almost always because they have functions that are not quite clear in what they do and then they piece them together and the picture becomes even murkier.

You really should not be passing by reference, especially not in a simple function that has no obvious need to change the things being passed in.

You are passing both params by reference even though you don't actually change one and you return the other. There isn't even a performance benefit here as the integer value and the reference are going to be the same size. (And if you wanted a performance gain you should use a const ref)

You describe the function with:

//Function that calculates the remainder from the given input.
//Returns: the remainder

What does this mean? There is no such thing as a remainder for a number, remainder is an operation that requires two inputs. It's not clear at all what the "remainder" here actually is, and it only seems to matter if it is zero or not.
 

wolfmat

Confirmed Asshole
Notrollious:
After fucking things up initially, to make it up to you, let me give you a few legit tips regarding iterating in search of a number with which you can divide a non-prime:
1. If your input is even, it is not a prime if it is greater than 2. (modulo 2 helps there)
2. If your input ends in 5 or 0, and is greater than 5, it is not a prime.
3. You only have to iterate up to 1/3 of the input to search for a divisor sans remainder. (We already excluded even numbers in 1.)
4. To make 3. easier, iterate downwards instead of upwards (start at the integer at or right below 1/3 of input).

Checking for primality by iterating is impractical, but you surely knew that already.
 
Margalis said:
Edit: Now looking at your solution. Comments:

You only need to loop up to 1/2 the number, no integer is divisible by a number that's more than it's half.

Yeah, I noticed that and fixed that.

Returning the remainder is a little weird. In plain english what is it that this function does? The best way to program (IMO) is to write functions that are very clear in what they do and piece them together. When people run into problems it's almost always because they have functions that are not quite clear in what they do and then they piece them together and the picture becomes even murkier.
I totally understand what you're saying. It was one of my left overs from a test I had, when I was trying to determine what was wrong. I think I should just do return 0; there, right?

You really should not be passing by reference, especially not in a simple function that has no obvious need to change the things being passed in.

You are passing both params by reference even though you don't actually change one and you return the other. There isn't even a performance benefit here as the integer value and the reference are going to be the same size. (And if you wanted a performance gain you should use a const ref)

Well, the issue I ran into was the fact that no matter what, the function kept telling me that every number was composite (r=0). referencing the remainder helped solve my problem.

//Function that calculates the remainder from the given input.
//Returns: the remainder

What does this mean? There is no such thing as a remainder for a number, remainder is an operation that requires two inputs. It's not clear at all what the "remainder" here actually is, and it only seems to matter if it is zero or not.

Me being sloppy. >_>

I changed it to read "Returns: true if remainder >=1, false if remainder = 0", something along those lines, where it's clear what the function is doing.
 

Margalis

Banned
When I was a TA for a programming class in Java the single most common problem I saw was that people would have a static method, then in order to get their program working they would make something else static, and in the end the entire program was all static methods. They ended up with something that worked but was a disaster.

Generally you don't want to change things just to fix problems that you don't quite understand, you want to understand the problem and do things the right way.
 
Yeah. I'm starting to see where that's going to hit me. It's just a matter of working on thinking dynamically and in computer logic (and not my normal logic, which I do consider myself fairly decent at).

I am picking things up day by day, and I'm understanding things better. It took me an hour and a half to figure out what I did wrong, and while it may not be the prettiest right now, at least I know how it works.

Here's a general question, it would be worth setting some kind of goal for the near future? I.e. being able to program something like tetris from scratch or something similar? I assume it would help me understand how things come together like that, or would I be setting myself up for problems down the road?
 

barnone

Member
Can someone show me how to create a deep copy of a dynamically allocated object?

In my main I create two vectors:
Code:
 std::vector<Polygon*> polygons;
 std::vector<Triangle> triangles;
where the polygons vector holds a few shapes and includes the triangles in the triangles vector.

After I create three points for a triangle, I do this:
Code:
triangles.push_back(Triangle(p0, p1, p2));
polygons.push_back(new Triangle(p0, p1, p2));

the constructor for my Triangle class looks like this:
Code:
Triangle::Triangle(const Point& p0, const Point& p1, const Point& p2) {
  m_points = new Point[3];
  m_points[0] = p0;
  m_points[1] = p1;
  m_points[2] = p2;
}

I've kind of forgotten how to create a deep copy system since last semester. From what I can tell, there is currently a shallow copy made for the points between the heap triangle and the triangle on the stack, and a dangling pointer is being created for the points (for the triangle created on the stack).

Do I need to create a copy constructor?
 

maharg

idspispopd
barnone said:
the constructor for my Triangle class looks like this:
Code:
Triangle::Triangle(const Point& p0, const Point& p1, const Point& p2) {
  m_points = new Point[3];
  m_points[0] = p0;
  m_points[1] = p1;
  m_points[2] = p2;
}

Just don't make m_points a pointer.

Code:
Point m_points[3];

// not

Point *m_points;

You're probably leaking like a sieve doing that. And it's 'shallow' because it's copying the pointer, not the points object itself.
 

barnone

Member
maharg said:
Just don't make m_points a pointer.

Code:
Point m_points[3];

// not

Point *m_points;

You're probably leaking like a sieve doing that. And it's 'shallow' because it's copying the pointer, not the points object itself.


Thanks! The code was provided by my professor for us to debug. I'm not sure if the goal is for us to figure out how to patch up this leaky sieve, or for us to change it to an array on the stack that will always be a size of three points (which makes more sense to me).

I'll ask the prof about it.
 

Escape Goat

Member
I know its a C++ thread but I had a Visual Basic question that I think some of you could answer.


Is it possible to use both a RemoveAt AND a Remove.Text to remove selections in a combo box?

Like I can either select the choice from the list or i can simply type it into the combo box and have it perform the remove either way.
 

Escape Goat

Member
Yeah, I have

With GenreComboBox1
If .SelectedIndex <> -1 Then
.Items.RemoveAt(.SelectedIndex)

DialogResponseResult = MessageBox.Show("Remove the selected genre?", "Remove genre", _

MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2)

Else
MessageBox.Show("Select the genre to be removed", _
"No selection made", MessageBoxButtons.OK, _
MessageBoxIcon.Exclamation)
End If
End With

Wish i knew how to format it for you but thats what I have.
 

Kalnos

Banned
Not sure why you would ever need to remove by specifying the name, but it could certainly be done a number of ways. The easiest way I can think of is just using an event (I.E. typical button click event). You can generate one by putting a button on the form and then double clicking it.

User pressed button --> Press button event is fired --> If combobox.Text is not "" (empty string) --> Remove(combobox1.Text). Then you can display your "item removed" or "item not removed" messages and then set combobox1.Text = "" so that it defaults back to normal.

That way, if the user had an item selected that they didn't want then all they would have to do is press the button. Alternatively, they could also type what they didn't want and it would also be removed.
 

barnone

Member
My friend and I are trying to think of a programming project for our class that implements the following concepts:

• It must include at least one level of inheritance with an abstract base class.
• It must demonstrate abstraction by composition of at least two self–written classes.
• It must use at least one polymorphic container class (self–made or from the standard library or from Qt).
• It must use serialization and deserialization of objects via XML.
• It must use aggregate operations on the polymorphic container.
• It must be suitable for scripting by providing appropriate command–line argument processing and return codes.
• Funcionality must be demonstrated by appropriate Python scripts

Now as I've only been a CS student for a year, I don't feel experienced enough to create my own feasible project. The suggested project is a phone billing system, but extra credit is offered for a unique project. Anyone have some suggestions or can someone stimulate my thoughts on how to be creative for this?
 

Venfayth

Member
I've only taken one or two programming classes, I understand the basics, but can someone explain something for me?

My friend and I are working on a program to play card games. We're currently figuring out how we can define a deck and shuffle it. Currently our plan is to represent a deck with a 2d array that contains order information and a cardid.

string deck[][];

a visual example of what we're trying to accomplish would be something like:

order | cardid
[0] 4 | 358
[1] 1 | 38
[2] 5 | 14
[3] 3 | 70
[4] 2 | 54

We want the order to be separate from the index, is that necessary? It seems like it would be easier to manage the cards order' this way.

Also, when defining a function to have a 2d array passed to it, why is it necessary that the second dimension have its size defined?

For example

void someFunction(int args[][]);

results in an error, whereas

void someFunction(int args[][5]);

works perfectly.
 
Acullis said:
I've only taken one or two programming classes, I understand the basics, but can someone explain something for me?

My friend and I are working on a program to play card games. We're currently figuring out how we can define a deck and shuffle it. Currently our plan is to represent a deck with a 2d array that contains order information and a cardid.

string deck[][];

a visual example of what we're trying to accomplish would be something like:

order | cardid
[0] 4 | 358
[1] 1 | 38
[2] 5 | 14
[3] 3 | 70
[4] 2 | 54

We want the order to be separate from the index, is that necessary? It seems like it would be easier to manage the cards order' this way.

Also, when defining a function to have a 2d array passed to it, why is it necessary that the second dimension have its size defined?

For example

void someFunction(int args[][]);

results in an error, whereas

void someFunction(int args[][5]);

works perfectly.

Seems like the opposite to me. Order should be the index if you want it to be simple to manage the order.
 

Venfayth

Member
cpp_is_king said:
Seems like the opposite to me. Order should be the index if you want it to be simple to manage the order.
Well this was my original thought process:

If we can change the order but leave the index alone that'll save us a lot of hassle dealing with messy arrays. Our function that will eventually list the deck will just sort based on the "order column" - but that ends up being almost as messy as reordering the cards based on index every time we shuffle.

I don't know which way ends up being cleaner :/

edit: nevermind i'm a moronjkladjflkjsd
 

Wichu

Member
Use objects! Card and Deck classes will be useful - your Deck class could contain an ordered list of cards, and a second list of the current deck order. Or even a std::map<int, Card>; maps automatically sort their elements, so if you assign each card a unique key (position in the deck), you don't need to worry about traversing the cards in order.
 
Acullis said:
Well this was my original thought process:

If we can change the order but leave the index alone that'll save us a lot of hassle dealing with messy arrays. Our function that will eventually list the deck will just sort based on the "order column" - but that ends up being almost as messy as reordering the cards based on index every time we shuffle.

I don't know which way ends up being cleaner :/

I guess I don't see the problem. If you want to list the deck, just iterate from 0 to 51 and print out each card in the array. Since order is the index, you are printing out the cards sorted according to however they were shuffled, which seems to be the correct thing to do anyway.

It also makes your arrays one-dimensional, and thus easier to work with.

If you want to shuffle your deck, then do something like this:

Code:
for (int i=0; i <= 51; ++i)
{
    //pick a random index in the array after this index, up to and including index 51
    int other = generateRandomNumber(i+1, 51);  

    swap(deck[i], deck[other]);
}

I guess I'm not seeing what the problem is with having the array itself just always be ordered in whatever order your shuffle resulted in.
 

Venfayth

Member
cpp_is_king said:
I guess I don't see the problem.

There's no problem. This was a case of me coming to a false conclusion about why I needed to do something a certain way, and then never questioning it. >_< Sorry! :p

But! I still am curious about why you need to include something in the second bracket when you're passing a 2d array to a function, so if anyone wants to try to explain it to me in a high level way, I'd appreciate it.
 

Wichu

Member
2D arrays are just convenient notation for 1D arrays:
Code:
1 2
3 4
5 6
7 8
9 10
is stored as:
Code:
1 2 3 4 5 6 7 8 9 10
To use 2D notation in a function, it needs to know the width of the array so it can properly index the underlying 1D array. For example, if your array was actually:
Code:
1 2 3 4 5
6 7 8 9 10
it would also be stored as
Code:
1 2 3 4 5 6 7 8 9 10
However, element [1][1] of the first array is different to element [1][1] in the second (4 in the first, 7 in the second). To get the right one, you also need to tell the compiler the width of the array.
 

barnone

Member
Can anyone explain to me the meaning of the argument for this Qt QObject constructor?

QObject ( QObject * parent = 0 )

Also, why must a class derived from QObject contain a QObject* pointer argument in its own constructor? EDIT: Does it have to store this pointer as a private data member, and if so what is this pointer commonly used for?
 
barnone said:
Can anyone explain to me the meaning of the argument for this Qt QObject constructor?

QObject ( QObject * parent = 0 )

Also, why must a class derived from QObject contain a QObject* pointer argument in its own constructor? EDIT: Does it have to store this pointer as a private data member, and if so what is this pointer commonly used for?

I've never used Qt before, but I can probably answer it anyway. Windowing systems typically represent things in a hierarchical structure. For example, when you reply to a message on this forum, the white box where you type your message is most likely a "child" of the larger grey box that also contains buttons and stuff you can use to control formatting. That grey box, in turn, is likely a child of the larger rendering area that your browser draws web pages in, which is in turn a child of the entire browser application.

Of course, windows might contain other children besides just other windows. there might be internal objects that are not visible to the user but are basically implementation details, but by being "associated" with a certain object or window, they are essentially children.

Often, these objects need to talk to their "parents" to let them know about things that are going on, or to access certain properties or information controlled by their parents.

The parent parameter to the constructor simply creates the hierarchy. You are essentially saying that the object you're creating is a child of whatever you pass into the constructor. If you pass NULL, you are saying it is a root-level object.


That's about the best answer I can give without a more specific scenario in which I could go further and explain why you would actually want a parent/child relationship
 

barnone

Member
cpp_is_king said:
I've never used Qt before, but I can probably answer it anyway. Windowing systems typically represent things in a hierarchical structure. For example, when you reply to a message on this forum, the white box where you type your message is most likely a "child" of the larger grey box that also contains buttons and stuff you can use to control formatting. That grey box, in turn, is likely a child of the larger rendering area that your browser draws web pages in, which is in turn a child of the entire browser application.

Of course, windows might contain other children besides just other windows. there might be internal objects that are not visible to the user but are basically implementation details, but by being "associated" with a certain object or window, they are essentially children.

Often, these objects need to talk to their "parents" to let them know about things that are going on, or to access certain properties or information controlled by their parents.

The parent parameter to the constructor simply creates the hierarchy. You are essentially saying that the object you're creating is a child of whatever you pass into the constructor. If you pass NULL, you are saying it is a root-level object.


That's about the best answer I can give without a more specific scenario in which I could go further and explain why you would actually want a parent/child relationship


Thanks! That makes a lot of sense.

Does storing the pointer to the parent class (as a private data member) just keep the structure of the hierarchy apparent to the user? I am just starting using Qt, and I am curious as to what operations people actually perform on this data member.
 

Kalnos

Banned
barnone said:
Does storing the pointer to the parent class (as a private data member) just keep the structure of the hierarchy apparent to the user? I am just starting using Qt, and I am curious as to what operations people actually perform on this data member.

If you're referring to passing an instance of a class through the constructor of another as an argument and then storing a pointer to it then that's a design pattern. It has a number of uses but the one I can think of is making sure that Class A exists before instantiating Class B.

I.E.

Code:
Class InsuranceCompany
{
     InsuranceCompany()
}

Class InsurancePolicy
{
    Private InsuranceCompany c;

    InsurancePolicy(InsuranceCompany c)
    {
        this.c = c;
    }
}

Basically, if Class B's functionality depends on Class A existing then this is a good way to make sure no one can create B unless you have an instantiated Class A to pass it. Also, of course, it's a good way to pass data between classes without breaking a certain level of encapsulation.

I might have also completely missed the point of your question. That's if you're referring to objects of the same type, I.E. same class. :D
 
barnone said:
Thanks! That makes a lot of sense.

Does storing the pointer to the parent class (as a private data member) just keep the structure of the hierarchy apparent to the user? I am just starting using Qt, and I am curious as to what operations people actually perform on this data member.

It's not necessarily that people are directly performing operations on the parents, it's that the structure needs to exist just for things to even work at all.

For example, the part of Qt that is responsible for rendering a window needs to start at the root level, then draw the window, then draw all its children, then draw all of those children's children, and so forth and so on until it's done. Without that structure being represented, it's impossible.

That's just one use. But suppose you had a button that was part of another window, and the button was labeled "set window color to red". when you click the button, the parent has to change its background to red. This is another situation where you need to be able to get the parent of an object.
 

Wichu

Member
cpp_is_king said:
That's just one use. But suppose you had a button that was part of another window, and the button was labeled "set window color to red". when you click the button, the parent has to change its background to red. This is another situation where you need to be able to get the parent of an object.
In Qt, the window would connect a slot that changes its colour to the button's pressed (or whatever) signal. I'd imagine there are situations where it would be useful to have a pointer to the object's parent, though.
 
Wichu said:
In Qt, the window would connect a slot that changes its colour to the button's pressed (or whatever) signal. I'd imagine there are situations where it would be useful to have a pointer to the object's parent, though.

The other direction is equally important. The parents need to access their children. I imagine the Object constructor calls some method on its parameter to add itself to a list of the parent's children. Ultimately, the relationship just needs to exist for countless reasons, some of which might be important to you, the programmer, and some of which is important to the framework itself. And passing the parent to the constructor is how you create the relationship
 

Slavik81

Member
barnone said:
Can anyone explain to me the meaning of the argument for this Qt QObject constructor?

QObject ( QObject * parent = 0 )

Also, why must a class derived from QObject contain a QObject* pointer argument in its own constructor? EDIT: Does it have to store this pointer as a private data member, and if so what is this pointer commonly used for?
The main purpose of the parent on a QObject is memory management: when a parent is deleted, it destroys all its children. There's also some stuff you can do by traversing the children of a QObject. You do not have to provide a parent if you don't want to. QObjects work fine without them.

People here are talking about windowing systems, and that's the purpose of the parent for QWidgets. For those, the parent is a part of determining the arrangement of GUI elements. A widget with no parent becomes a floating window, otherwise it is placed inside the widget it is parented to.

Qt has great documentation. Check out http://doc.qt.nokia.com/stable/classes.html

As you're new to Qt, you may also want to check out some of their introductions to Qt concepts, found here. Things I think are particularly important include:
Signals and Slots
Object Model
Object Trees and Ownership
Container Classes
 
Status
Not open for further replies.
Top Bottom