Jump to content

  • Log In with Google      Sign In   
  • Create Account

Rattenhirn

Member Since 29 Jun 2004
Offline Last Active Today, 03:20 AM

Posts I've Made

In Topic: Why do most people recommend Python

19 September 2016 - 03:49 AM

C++ is also great and definitely super useful. There are also loads of resources out there, but it has no real recommended best way of doing things. It's a multi paradigm language, where as most try to stick to a certain paradigm like OOP, functional, prototype based, purely procedural, ...

Different resources will constantly contradict each other. This is not a bad thing (in fact, I think it is a good thing), but it can be very confusing to beginners and adepts alike.

 

But ultimately it's up to you. No language will  make learning to program super easy, because it is hard and takes more than a lifetime to master. All the starting language can do is to move common pitfalls that cause frustration when learning out of the way. Even if a language manages to hide a certain complex topic away really way, at some point you'll need to tackle this topic. There's no escape, all abstractions are leaky! :)


In Topic: Why do most people recommend Python

19 September 2016 - 02:41 AM

People recommend Python because they hear other people recommend Python.

 

It's not a bad choice and it's available for free on pretty much every platform and there are tons of resources available.

I don't think closeness to spoken language is a good thing, it just leads to more confusion. Otherwise, everyone would recommend COBOL. :)

 

Personally, I prefer strongly typed languages and would recommend starting with C for system level programming or C# for application level programming.

They are also available for free on pretty much every platform and there are also tons of resources available.

 

I would not recommend Swift. It is not very well established and is still changing rapidly. It is really only useful in an Apple environment, and Apple wants to move its users as far away as possible from mainstream technology to keep their scent of exclusivity. Also, since it is still relatively new and not widespread at all, the number of resources at ones disposal are also limited.

 

However, as you correctly pointed out, ultimately all programming languages uses similar context, because they are abstractions of how computers work. So, if a language teaches you programming concepts and how computers work, it will be fine.


In Topic: GameObject class doesn't draw a image but a white box instead

12 September 2016 - 12:51 PM

Oh, I see. Did some more reading on it and I (finally ^^) understand. Thanks a lot for the help
 

 

Yay!


In Topic: GameObject class doesn't draw a image but a white box instead

10 September 2016 - 03:47 AM

I think the fundamental confusion for you here is, that in C++ there's a difference between these two cases:

Case 1:

MyClass myObject = MyClass(12345); // calls the MyClass constructor

Case 2:

MyClass myObject; // calls the MyClass default constructor

myObject = MyClass(12345); // creates a temporary MyClass object, copies it into myObject and destroys the temporary again

 

When you write a constructor that initializes members in the body and not in the initializer list, like you did in MainMenuState, you have Case 2.

Besides being a bit inefficient this usually is no problem, unless MyClass cannot be copied safely, as is the case with sf::Texture.

 

For this reason, I discourage the use of the "initialization written as assignment" notation, so this situation can never arise:

Case 1:

MyClass myObject(12345); // calls the MyClass constructor

Case 2:

MyClass myObject; // calls the MyClass default constructor

myObject(12345); // compile error!

 

In additon the NonCopyable idiom I referred to earlier should be used to make it impossible to unintentionally copy objects of classes that can't be copied safely.

 

Here's a longer example illustration the issue, I've written and tested it here, so you can just paste and run it.

#include <iostream>

using namespace std;

class InternalTexture
{
public:
    InternalTexture() : data(123456) { }
    int data;
};

class Texture
{
public:
    Texture()
        : internal(new InternalTexture())
    {
        cout << "Texture::ctor" << endl;
    }
    
    ~Texture()
    {
        cout << "Texture::dtor" << endl;
        delete internal;
    }
    
    InternalTexture* internal;
};

class Sprite
{
public:
    Sprite()
    {
        texture = Texture();
    }
    
    Texture texture;
};

int main()
{
   // Case 1:
   {
      cout << "Texture only:" << endl; 
      Texture texture = Texture();
      cout << "texture.internal = " << texture.internal->data << endl;
   }
   
   // Case 2:
   {
       cout << "Texture in sprite:" << endl;
       Sprite sprite;
       cout << "sprite.texture.internal = " << sprite.texture.internal->data << endl;
       // crash in Texture::dtor
   }
   
   return 0;
}

InternalTexture can't be copied safely, so Case 2 will fail. This is what I think happens inside sf::Texture, although the implementation there is more sophisticated as it knows that it refers to an invalid "InternalTexture" and handles it by that dreaded white square.

 

You can try to fix Case 2 be doing one or more of these:

1) Fix "Texture", by correctly applying the "rule of 3" (look it up) and implementing copy constructor and copy assignment operator

2) Fix "Texture" by making it "uncopyable" by making copy constructor and copy assignment operator private (NonCopyable idiom)

3) Fix "Sprite" by correctly using initializer lists to initialize its members. Note that Sprite would need to be fixed by applying 1 or 2 as well.

4) Make everything way more complicated (and fun!) by learning about C++ 11 move semantics

 

I hope that helps!


In Topic: GameObject class doesn't draw a image but a white box instead

04 September 2016 - 12:40 PM

The code looks complete now and you replaced inheritance with composition, great!

 

What struck me when reading it is, that you copy the Sprite once in the GameObject constructor. Here you should really use initialization lists when initializing members in a constructor, and that might also be the cause of the issue.

 

Here's how to initialize a member without making an extra copy:

GameObject::GameObject(std::string m_texturePath, float m_x, float m_y)
	: _sprite(m_texturePath, m_x, m_y);
{
}

I don't know much about SFML, so I took a quick peek at the documentation. Google took me here: http://www.sfml-dev.org/tutorials/2.0/graphics-sprite.php

 

Curiously it has a section talking about the "white rectangle problem", which tells you that you have to manage the lifetime of sf::Texture instances very carefully. That's not very beginner friendly, but I'm sure they had their reasons. Unfortunately it seems that they didn't put any measures in place to stop people from committing this mistake.

 

So, given the fact that you (probably unintentional) copy both the sprite and the texture around, it is unlikely that their internal state is still consistent. The above code snippet should fix that.

 

Bonus info: If you have a class that can't be copied safely, like your Sprite class, you can emply the non copyable idiom to get the compiler to tell you if you do it by mistake:

https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-copyable_Mixin

 

I hope that helps!


PARTNERS