Benefit of copying pointer class arguments to class members? - c++

I have a player class that uses my DirectX Graphics class to create surfaces and draw sprites.
I am passing the graphics class as a pointer to the player class methodlike this:
**game.cpp**
m_pPlayer->Init(Graphics* graphics);
Inside the player class my Init method passes the pointer to another pointer method. Is there any benefit to creating another graphics pointer in the player class and copying the pointer argument instead?
So this:
**player.cpp**
m_pSurface->Init(graphics, m_width, m_height);
vs this:
**player.cpp**
m_pGraphics = graphics;
m_pSurface->Init(m_pGraphics, m_width, m_height);
I know that having a m_pGraphics pointer allows me to reuse the pointer again in the same class, such as my drawing method but I call the method in the player class anyway so can't I just keep passing the pointer over and over again?

This is just a matter of style and is unlikely to have any effect on performance. Copying pointers is very cheap and I would leave it to the compiler to optimize.
If player uses the Graphics object a great deal it would be reasonable to store a pointer in a member variable instead of passing it in all the time. It may make the member function signatures on player shorter which is good.
You do need to be sure that the member pointer to the Graphics object remains valid whenever it is used. Is it still the correct Graphics object and is it still alive? If you pass the pointer every time you might not have this complication.

Related

Using a unique_ptr as a class member variable

I have a class Page which needs a Background object (in my project each page has a background). The Background is the base class of other classes (e.g. RuledBackground or DottedBackground) that specify the background in more detail. Because of this, I need polymorphism so I have to store the Background object using a pointer. However, since each Page essentially "owns" a unique Background object I thought I would use a std::unique_ptr<Background> in my Page class, so the background of each page is automatically deleted when the page is destroyed. The code below illustrates my class structure:
class Page{
public:
Background* background() {
return m_background.get();
}
private:
std::unique_ptr<Background> m_background;
};
In the code above instead of returning the unique_ptr, I am directly returning the raw pointer for the background, because it is my understanding that passing around a raw pointer is fine (or is it not?). The problem I see with my approach is to figure out how to initialize the raw pointer from outside the class, something like this
void setBackground(Background *bg){
m_background = std::make_unique<Background>(bg);
}
seems quite bad (since I suppose I will need to create the raw pointer somewhere).
The other approach I thought about is to be make the unique_ptr a public member variable and return a reference to it and then I can initialise it from outside the class.
What would be the most elegant and safest solution to what I just described? Is there a better alternative that does the same thing?

I can't access members of a child class through functions, how do I?

Okay, so my situation is really complex to a relativity new person to C++ like me. I'm making a game (AGK library) and I have a framework class that is the base class for all of the game's objects to have standard functions like frameEvent and such that are to be overwritten by the child object.
That's all fine and dandy, and I've gotten about 70% through development, but I ran across one vital problem.
To make life easier while processing the game, each object that is a part of the game is just a pointer in a vector of type Framework*. Framework being the base class. I was told that making it a pointer allows me to have child objects of different types as long as they're a pointer as well. So far it's worked out.
Every frame, the global object runs through the vector of all the objects and runs their
frameEvent
frameEndEvent -- Can't be overriden
drawEvent
They're really just functions. So in the enemy's bullet class, I need to check if it collides with oPlayer, so I have a functions in the global class (The global class is passed to the objects in their frame event so they can communicate with other objects.) that grabs a given object.
It searches through all of the objects to find the parameter object -- so if I pass new oPlayer, it will return the real oPlayer pointer in the game.
When the bullet collides with the player, it needs to lower the player's health and then destroy itself. So at the create function for the bullet, it creates a dummy player then locates the real one using the global class function. The code is
//Find the player
oPlayer* tempPlayer = new oPlayer;
playerChecker = ObjGlobal->classToObject(tempPlayer);
tempPlayer->objectDestroy();
That code works, but it needs playerChecker to be type Framework* because that's what classToObject returns. But when I later use that pointer, I can't access the player's members even though that's the player's pointer.
playerChecker->hitPoints--;
hitPoints is exclusive to oPlayer. I think it's called object splicing or slicing, but I thought that's what using pointers fixed.
So I tried to make playerChecker type oPlayer*, but it says that Framework* can't be converted to it. So I have no idea what to do.
Any help is greatly appreciated.
Your Framework* from classToObject can be downcast to a oPlayer* using a dynamic_cast, like so:
oPlayer* playerChecker = dynamic_cast<oPlayer*>(ObjGlobal->classToObject(tempPlayer));
if (oPlayer) {
// cast succeeded, do stuff with the pointer
}
dynamic_cast is a C++ type cast operator just like the C-style cast, with some special properties. It is specifically designed to convert between pointers or references to polymorphic objects (like your oPlayer, which can be treated as both a Framework and an oPlayer). It also adds a run-time check which verifies that the object you're trying to downcast is indeed an instance of the class you're trying to cast to. If it isn't, it will return a null pointer, or in the case of references, throw an exception.
Your code will also work with a C-style cast or a static_cast (which is much like a C-style cast with compile-type type checking).
static_cast<oPlayer*>(ObjGlobal->classToObject(tempPlayer)) // static_cast
(oPlayer*)ObjGlobal->classToObject(tempPlayer) // C-style cast
These have less overhead because of the lack of a run-time check, but that also means that they are unsafe unless you can guarantee that the pointer you're casting points to an object of the correct type. Also, since dynamic_cast has a very specific use, it makes it clear what your intent is.
What's the error you're getting? Please post this, as we can't offer much help otherwise.
If I had to guess, you forgot to add public: to your class FrameWork. This, or you don't have setters/getters in your class.

passing a vector member variable by reference to another class method

NOTE: I use pseudocode in my question
lets say i have a class called circle with an interface called
circle.h which
i also have a method called readdata but this is defined in another
class called rectangle(rectangle.h is the interface )
i want to call the method readdata in my circle class and pass in my
private member variable which is a vector. How can this be done? is it
correct to pass in a PRIVATE member variable by reference
to another class. Isn't this defeating the whole purpose of having
private member variables because now i am giving class rectangle
access to circle class vector variable since i pass it in by reference. Here is how i
do it(psuedocode)
circle.h
private:
vector<struct> vect;
public:
dataread()
circle.cpp
rectangle.h
readdata(vector &)
method dataread() //class method to fill up my struct
{
rectangle::readdata(vect); //i call rectangle readdata method but i
pass in a reference to my memebr variable....is this safe?
}
should i just declare the vector locally(in dataread method) and
assign it to the reference? any help would be greatly appreciated.
Right now it compiles but i have been told this is not good
programming practice
There is nothing wrong with passing references to private members to methods in other classes. For example:
void myClass::myMethod() {
std::copy(myVector1.begin(), myVector1.end(), myVector2.begin());
}
While that doesn't pass a reference to myVector1 directly, it does pass a writable iterator which is just about the same thing. The class is making a request for some object/function to do something with its data. So long as that other object/function only does what it is supposed to do, there's no problem.
I think I get what you are asking. Yes, you can pass a reference to your private data and No, you shouldn't do it. You can pass a const reference so that it can't be modified or pass a new vector with the contents copied. The best thing to figure out is why you need to do it that way, then figure out the best method for getting the data there.
Passing a pointer to a "private memory area" is not necessarily against the encapsulation idea because the object owning that memory area decides whom to allow access to. It doesn't allow "anyone to access it". On the other hand this doesn't look very natural.
You should return a pointer from the readdata method and use it in your circle instance.
At the same time doing this breaks a principle which I, personally, use: the one who allocates memory is responsible for it so it should also be the one frees it when appropriate. Taking this into consideration, it would probably be a good idea to return the actual vector and not a pointer to it (but this means copying a large amount of memory in case you're not using a compiler with "return value optimization").

Store object as pointer in class in C++

I'm learning C++ right now and I wanted to get a little advice on storing member variable objects. I want to store an instance of B in A, what is the best way to do this?
[EDIT] - I made the example more real world. I need to be able to construct and assign a texture at runtime and assign it to a game object.
class GameObject
{
public:
Texture texture;
};
....
GameObject gameObject;
Texture texture;
gameObject.texture = texture;
or
class GameObject
{
public:
Texture *texture;
};
....
GameObject gameObject;
gameObject.texture = new Texture;
I'm trying not to use pointers, but in some instances I feel I need to.
If you want to reseat(refer to different class B objects) your member variable to different objects use a pointer. If not just use an object.
Yes, it is a good idea to avoid pointers and if at you need to use them prefer smart pointers instead of raw/naked pointers.
It really depends on your particular solution and need. Both ways are just fine and acceptable. There is no "right way" to do most things in any language because your solution dictates how things should be done.
Though one thing to keep in mind is that if B is a large class with many data members, it would increase the size of A if you don't use pointers. Also, if you do use pointers, you need to make sure proper allocation and de-allocation is performed and not trust the user with doing that.
Here are what I think are good criteria to use:
Function: Is B PART of A or just related to it? A Car has an Engine, but the Driver is external. Another way to look at this is: Are they together from the start or is B assigned / given to A?
Construction: Is B fully known/definable at the time that A is constructed?
It depends on if you want A to control the memory of B.
Using pointers is very useful when passing objects back and forth between other objects. When you decide not to use pointers it is important to realize that as soon as an object goes out of scope, so do its member variables. Which can lead to problems if pointers to that object's members still exist elsewhere.
If this won't be an issue in your application I would avoid using pointers.

Passing objects and object oriented design best practices

I'm a university student learning programming. For practice I'm writing a blackjack program. I'm using C++ and doing an object oriented approach to this.
I have a Deck class designed that basically builds and shuffles a deck of cards. The deck generated is composed of an array of 52 Card class objects. That's what I have so far.
My plan is to have a Dealer object, which has a Deck of 52 Cards deal a Card to a second Player object and then deal to the Dealer's own hand.
My first question is: Is it bad practice to make the array of Card objects public in the Deck class?
I ask this because I consider the array an attribute and was taught that most attributes should be made private. I don't want to start using bad or lazy practices in my projects and want to do it the right way.
Another question: How are objects, such as the Card object used in my blackjack program, generally moved from within an object -like the dealer- to a second object like a player?
My first question is: Is it bad practice to make the array of Card objects public in the Deck class?
Yes. In general, data members should always be private. It is good OOP to create an interface with no associated data that defines what operations can be performed on the object, and then to provide a concrete class that implements that interface. The data is an implementation detail that should not be visible in the interface or even in the fully concrete class. As an example of why it is bad, you might implement your class using an array of Card objects right now, but maybe later you decide to use a bitset where a single bit indicates whether the card is or isn't present in the deck. If you make your Card array object public, changing the representation in that manner would break other users of your class; however, if you keep it private, you can make that change without impacting the users of your class.
Another question: How are objects, such as the Card object used in my blackjack program, generally moved from within an object -like the dealer- to a second object like a player?
It depends on whether the other object needs to access the original card object, whether the other object will hold onto the original object for a long time or only a short time, or if the other object is able to handle only a copy of the card. It also depends on whether the card is a concrete class or a polymorphic type, since polymorphic objects can only be passed by pointer or reference (because passing polymorphic objects by value will lead to code slicing). With concrete objects, you have the option to pass a copy unless you need to modify or access the original object, in which case a reference is needed. Choosing the right way to pass objects is somewhat complicated, but hopefully this will clarify:
Pass by value if:
It is a primitive type or small, non-polymorphic concrete type that does not need to be modified.
Pass by constant reference -- that is const T& for some type T -- if:
You do not need to modify the original object.
You do not need to read the original object outside of the scope of the function.
You do not need to read the object beyond the scope of the function, or the type
is non-polymorphic and cheap to copy, so you can create a copy if you need to hang onto
it.
Pass by reference -- that is T& for some type T -- if:
You need to modify the original object.
You do not need to read/write the original object outside of the scope of the function.
You do not need to read the object beyond the scope of the function, or the type
is non-polymorphic and cheap to copy, so you can create a copy if you need to hang onto
it.
Pass by constant smart pointer to a const -- that is const shared_ptr<const T>& for some type T -- if:
You need to read the original object both in the scope of the function and beyond.
You need to read the object both in the scope of the function and beyond, and the type is non-polymorphic so that it is not possible to safely create a copy of it.
Pass by constant smart pointer -- that is const shared_ptr<T>& for some type T -- if:
You need to read and write the orginal object both in the scope of the function and beyond.
I have given each of the above in deliberate order; you should try the first one that will suffice for the job, only moving onto the next if the previous is not sufficient. Also, I should add that boost::call_traits<T>::param_type can help you choose between passing by value and passing by constant reference in the case of concrete non-polymorphic types (it can determine, based on the size of the object, whether pass by value or pass by constant reference is better).
At least IMO, you're trying to overdo it. In reality, a card deck doesn't have any behavior -- it's just a bunch of cards. You don't have a dealer who tells the deck of cards to shuffle itself; you have a dealer who shuffles the deck. I'd do the same in a program -- the deck would just be an std::vector<card> that's owned by the dealer (and it should almost certainly be private).
For dealing, each player would have its own std::vector<card> for its hand. The dealer would then pass each player one card at a time by calling the player's deal (or whatever) member function.
My first question is: Is it bad practice to make the array of Card objects public in the Deck class?
Depends. But it is usually bad to expose data publicly.
This is because public items become part of the interface and thus must be maintained.
It would be better to make the array a private member then expose actions via the public interface. This will then allow you to change the private data later (for instance when you learn how to use a vector you may replace the array with a vector. If the array was public you would not be able to change the type without affecting every other type that used that fact that it was an array).
Principle: Hide implementation details.
This leads to a looser coupling between types.
Another question: How are objects, such as the Card object used in my blackjack program, generally moved from within an object -like the dealer- to a second object like a player?
Remove it from the array in one object (and shrink the array to show it has less cards (thus you may want a container type that can change in size)) Then put it into another array (container) in the destination object.
1) Generally, yes. Conceptually, the Player instances do not mess with the cards belonging to the dealer, so it should be private.
2) One way to do that:
struct Card
{
Suit suit;
Rank rank;
};
class Player
{
private:
void AddCard(Card card);
friend class Dealer;
};
class Dealer : public Player
{
public:
void DealTo(Player& player);
};
Dealer dealer;
Player player2;
dealer.DealTo(player2);