Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Evil_Greven
Feb 20, 2007

Whadda I got to,
whadda I got to do
to wake ya up?

To shake ya up,
to break the structure up!?
Right. I'm basically just using his code from above. He had inputId as an int, so I swapped it to a char array. An entry longer than MAX_CHAR would break his class anyway.

Using a string is a much, much, much better idea than this.

Though, for the comparison Bonfire Lit quoted, I seem to have swapped the order/comparison and forgot the this-> before gpa.

Adbot
ADBOT LOVES YOU

Bonfire Lit
Jul 9, 2008

If you're one of the sinners who caused this please unfriend me now.

Evil_Greven posted:

Though, for the comparison Bonfire Lit quoted, I seem to have swapped the order/comparison and forgot the this-> before gpa.

No, the code is correct - you don't actually need this-> there - but writing the comparison in reverse is certainly strange.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
If I want to make memory management go through alloc/free callbacks instead of using new/delete, it seemed like an option was to use placement new and directly call the destructor, but there's one piece of functionality that doesn't seem to work with that: Getting a pointer to the object from a pointer to a base class with a virtual destructor, so it can be freed. Is there a way to do that, or is operator delete "special" in having that capability?

Vanadium
Jan 8, 2005

Isn't that what dynamic_cast is for?

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!

Vanadium posted:

Isn't that what dynamic_cast is for?
Apparently it is, dynamic_cast<void*> does it.

Meat Beat Agent
Aug 5, 2007

felonious assault with a sproinging boner
Does dynamic_cast behave any differently when casting to void* than the other cast operators do?

ctz
Feb 6, 2003

daft punk railroad posted:

Does dynamic_cast behave any differently when casting to void* than the other cast operators do?

Yes, see 5.2.7/7 in C++98 or C++11.

Deus Rex
Mar 5, 2005

daft punk railroad posted:

Does dynamic_cast behave any differently when casting to void* than the other cast operators do?

From cppreference:

quote:

4) If expression is a pointer or reference to a polymorphic type, and new_type is a pointer to void, the result is a pointer to the most derived object pointed or referenced by expression.

This is useful, for example, if you have pointers to two different interface classes and want to see if they refer to the same object.

Deus Rex fucked around with this message at 15:34 on Mar 16, 2015

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
Is there a way to make Cygwin's gcc not export every symbol when building a DLL?

i.e. if I do this:
code:
#include <stdio.h>
void test()
{
	printf("Hi");
}
code:
g++ -s -fvisibility=hidden -fvisibility-inlines-hidden --shared -o testdll.dll test.cpp
... then "test" still winds up in the DLL export table.

Bonfire Lit
Jul 9, 2008

If you're one of the sinners who caused this please unfriend me now.

OneEightHundred posted:

Is there a way to make Cygwin's gcc not export every symbol when building a DLL?
ld should stop exporting every symbol if you either use a .def file or mark at least one symbol with __declspec(dllexport).

duck monster
Dec 15, 2004

Over the next few weeks I'm going to be hitting you guys with some pants on head level retarded questions. I'm trying to teach myself C++ again. First time I've properly used it since the early 90s so I've forgotten almost everything. o_O Fortunately it seems that C++11 addresses most of my criticisms I had of C++, so I figure its time I came out of the cold. I can do C and ObjC well enough, so I might as well finish the trifecta. I'm porting an old python Pygame game I wrote across to C++ using cocos2d-x (I know the ios cocos2d framework pretty well so conceptually thats not a drama).

Anyway question 1;-
code:
PlayerCraft* PlayerCraft::create()
{
    return (PlayerCraft *)PlayerCraft::createWithAtlas(1,cocos2d::Rect(0,0,94,99));
}
I have a base class SpaceCraftBase that is itself descended from cocos2d::Sprite that defines a static constructor "createwithathlas" that loads a particular png image, cuts out a segment of it and returns an instance of SpaceCraftBase.

The code above, also a static constructor calls createwithatlas on the ancestor, but I need it to return PlayerCraft rather than SpaceCraftBase Am I doing this right by coercing it to PlayerCraft, or is it just a SpaceCraftBase with a janky rvalue that I'm returning here, later on to bite me in the arse? How am I *suppose* to do it.

Telarra
Oct 9, 2012

You should only cast a pointer to types that are valid for the data it points to. In this case, SpaceCraftBase::createFromAtlas() is returning a SpaceCraftBase, which is not a valid PlayerCraft. Probably what you want to do here is make a PlayerCraft::createFromAtlas() that returns a PlayerCraft.

duck monster
Dec 15, 2004

That kind of loses the whole advantage of inheritance though? I have a number of different objects that need the same constructor because the whole chunk of code that slices up the assets , replaces the color key with alpha values and so on is kinda complex :/

edit: It seems to work the way I'm doing it. If I call a method defined only on PlayerShip with the returned object it seems to work. I don't know why?

duck monster fucked around with this message at 10:33 on Mar 22, 2015

raminasi
Jan 25, 2005

a last drink with no ice

duck monster posted:

That kind of loses the whole advantage of inheritance though? I have a number of different objects that need the same constructor because the whole chunk of code that slices up the assets , replaces the color key with alpha values and so on is kinda complex :/

edit: It seems to work the way I'm doing it. If I call a method defined only on PlayerShip with the returned object it seems to work. I don't know why?

:siren: The point of inheritance is not code reuse :siren:

While that's the kind of hard-and-fast rule that usually has a few real-world exceptions, it's a good starting point for program architecture.

With respect to your specific code: That static downcast is undefined behavior. (Tip: It's considered more idiomatic C++ to use static_cast and dynamic_cast over C-style casts.) We need to know more about your program design and inheritance hierarchy to give you some alternatives.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
I don't know what you're talking about with a "static constructor", and I think using that terminology might be confusing you. The usual name for the sort of construct you're using is a "factory". The create() and createWithAtlas() functions are not constructors.

If you want to construct a PlayerShip, you must invoke a PlayerShip constructor. The PlayerShip constructor does things like "allocating enough memory for the object", "setting up the vtable so that virtual method calls on the object work correctly", and "initializing all the fields of the object". If you don't invoke the PlayerShip constructor, and instead just try to cast some other object to look like a PlayerShip, then everything is basically guaranteed to break as soon as you try and do something that requires the object to actually be a PlayerShip - for example, accessing fields specific to PlayerShip objects, or invoking virtual methods on the object. If you never do anything that cares about the actual type of the object, then you're basically missing the point of inheritance and might as well just be passing bare structs around.

If you want to re-use the initialization code for your objects, the usual way to do that is to put in the actual constructor instead of in a factory method. Then, constructors for child classes simply call the base class constructor to initialize most of the object, and then the child class constructor only needs to initialize things specific to that child class. Alternatively, you can put the initialization code in a function and call it from the constructor to actually perform the initialization.

nielsm
Jun 1, 2009



Jabor posted:

If you want to re-use the initialization code for your objects, the usual way to do that is to put in the actual constructor instead of in a factory method. Then, constructors for child classes simply call the base class constructor to initialize most of the object, and then the child class constructor only needs to initialize things specific to that child class. Alternatively, you can put the initialization code in a function and call it from the constructor to actually perform the initialization.

I'm not sure if this is what you mean, but it's a pattern that only just occurred to me: Defining child classes whose only point is to have a different constructor, but do not define any new data or functions or override any virtual functions.

Is there a name for that?

sarehu
Apr 20, 2007

(call/cc call/cc)
Something better done with friend functions.

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



I'm trying to patch over a method call in a C++ application, but something isn't going right. I've "successfully" replaced the method at runtime, but the img format/dimensions appear invalid & the resulting test.png is 0 bytes. However, the call to the original function at the end succeeds, as I can see the image become sharpened in the GUI.

C++ code:
QImage overrideBlitzSharpen(QImage &img, int radius)
{
    printf("Image info %p: %d x %d @ %d (format %d)\n", &img, img.height(), img.width(), img.depth(), img.format());
    // example output: "Image info 0x10aee5be8: 0 x 0 @ 0 (format 0)"
    
    img.save("test.png", 0, 100);
    
    return (*originalBlitzSharpen)(img, radius);
}
Docs:
http://doc-snapshots.qt.io/4.8/qimage.html#image-formats
http://api.kde.org/kdesupport-api/kdesupport-apidocs/qimageblitz/html/classBlitz.html#a809992c7bd9627f058f60b0ab5f16d51

Suggestions?

Evil_Greven
Feb 20, 2007

Whadda I got to,
whadda I got to do
to wake ya up?

To shake ya up,
to break the structure up!?
Does printf() give you an address for the first parameter?

Also, can you actually get a signed decimal integer from the last parameter? Glancing at the reference links, img.format() returns a value of type Format.

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



Yes, I get an address (0x10aee5be8 in the example above).

The img.format() call returns 0 = QImage::Format_Invalid (see http://doc-snapshots.qt.io/4.8/qimage.html#Format-enum ).

duck monster
Dec 15, 2004

Ok. More dumb questions incoming.

I've got an object that maintains most of the game state (GameStage.h/cpp) and various objects representing sprites in the game. I've got most of this working, but I want to push a little bit of logic back into the sprites, because it seems to me like they 'own' that logic. The big one is the player ship working out distances to other spaceships to decide if any of them are targetable.

So I've got on the main game object a Vector<BadGuy *> full of badguys, and I want to push this to the user spaceship so it can do its thing.

The problem is, I end up with a circular dependency because the user spaceship declares it needs GameStage.h to ask it for those values, and of course Gamestage.h needs a a reference to the user spaceship so it can instantiate it and so on.

Whats the normal approach to resolving this?

raminasi
Jan 25, 2005

a last drink with no ice
Forward declarations. (I'm on a phone so I'm just giving you the term to Google.)

Spatial
Nov 15, 2007

duck monster posted:

Whats the normal approach to resolving this?
The programming language being designed properly. :v:

Marta Velasquez
Mar 9, 2013

Good thing I was feeling suicidal this morning...
Fallen Rib

GrumpyDoctor posted:

Forward declarations. (I'm on a phone so I'm just giving you the term to Google.)

Because Vector<BadGuy *> only requires a pointer to BadGuy, not the full class definition, you can just put `class BadGuy;` above the GameStage class in GameStage.h rather than #include'ing the whole BadGuy.h file.

Evil_Greven
Feb 20, 2007

Whadda I got to,
whadda I got to do
to wake ya up?

To shake ya up,
to break the structure up!?

duck monster posted:

I've got most of this working, but I want to push a little bit of logic back into the sprites, because it seems to me like they 'own' that logic. The big one is the player ship working out distances to other spaceships to decide if any of them are targetable.

If: a) it already works, b) the only reason to change it is to be more 'OOP' and c) changing it would require a significant redesign of the program... don't?

KaneTW
Dec 2, 2011

Rewrite everything in Haskell with <FRP framework of your choice>

duck monster
Dec 15, 2004

GrumpyDoctor posted:

Forward declarations. (I'm on a phone so I'm just giving you the term to Google.)

Yep this nailed it. Just told it about the other class at the top, and its all good.

edit:

quote:

Because Vector<BadGuy *> only requires a pointer to BadGuy, not the full class definition, you can just put `class BadGuy;` above the GameStage class in GameStage.h rather than #include'ing the whole BadGuy.h file.
exactly this. Works great.

duck monster fucked around with this message at 13:29 on Mar 30, 2015

duck monster
Dec 15, 2004

Evil_Greven posted:

If: a) it already works, b) the only reason to change it is to be more 'OOP' and c) changing it would require a significant redesign of the program... don't?

It didn't already work completely, and the reason was because putting the logic in the sprite class itself is the design that fits the particular framework, since the events are handled by cocos2d as registering to the individual sprite and it wasn't particularly logical where I had it before.

Also: Vectors, where have you been all my life! Trying to stuff things in C style arrays was getting messy.

Thanks for putting up with my pants on head stupid questions guys. I pretty much have forgotten everything I learned, like 20 years ago when I did my unit on C++ so its not quite as easy as falling off a bike here. However if experience has taught me anything, the best way to learn to ride bikes by falling off them repeatedly. So I'm writing a game, because that poo poo involves lots of bike crashes.

duck monster fucked around with this message at 13:33 on Mar 30, 2015

CommunityEdition
May 1, 2009
So, the company I've learned C++ while working for had a "no templates or multiple inheritance" rule, and essentially hewed as close to C in memory management and types as possible. Now that I'm out, I'm trying to figure which of the modern stuff I'll need to know. I know I'll need to pick up STL, but what else should I be knowing?

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Zilla32167 posted:

So, the company I've learned C++ while working for had a "no templates or multiple inheritance" rule, and essentially hewed as close to C in memory management and types as possible. Now that I'm out, I'm trying to figure which of the modern stuff I'll need to know. I know I'll need to pick up STL, but what else should I be knowing?
Smart pointers (which are part of STL but are the most important thing so merit special mention).
Containers (which, too, are also STL but are a much important thing - vectors, maps, sets and lists all have their valuable places very often).
Probably stick with no multiple inheritance though.
I can't think of much of a "what else", STL is most of the things. new and delete, I suppose, if you were really doing C-style memory management. Or rather, new and not delete because you're using smart pointers now.

Deus Rex
Mar 5, 2005

Zilla32167 posted:

So, the company I've learned C++ while working for had a "no templates or multiple inheritance" rule, and essentially hewed as close to C in memory management and types as possible. Now that I'm out, I'm trying to figure which of the modern stuff I'll need to know. I know I'll need to pick up STL, but what else should I be knowing?

Since roomforthetuna covered nice things in the standard library I'll mention some language features that might interest you.

Move semantics are a cool addition and probably the most crucial new language feature in "modern" C++ (C++ starting from C++11). Without move semantics, std::unique_ptr couldn't exist, for example. It also lets you cheaply move things like strings and vectors around from one owner to another without copying the vector's allocated/owned data.

auto and "ranged for" are also very nice. Instead of writing:
C++ code:
for (const std::some_container<SomeHorribleType>::some_iterator it = xs.begin(); it != xs.end(); ++it) {
    const SomeHorribleType& x = *it;
    // ...
}
You can write:
C++ code:
for (auto it = xs.cbegin(); it != xs.cend(); ++it) { // auto deduces the type of `it` 
    auto& x = *it; // deduces type of `x` as `const SomeHorribleType&`
    // ...
}

// OR

for (const auto& x : xs) { // ranged for, using const iterator
    // ...
}

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

Zilla32167 posted:

So, the company I've learned C++ while working for had a "no templates or multiple inheritance" rule, and essentially hewed as close to C in memory management and types as possible. Now that I'm out, I'm trying to figure which of the modern stuff I'll need to know. I know I'll need to pick up STL, but what else should I be knowing?

That's not a bad thing. Smart pointers and STL containers are useful but everything else is a total pain in the rear end.

CommunityEdition
May 1, 2009
Thanks guys. A few years ago I would have called things like auto and those smart pointers namby-pamby, but I've just about had that beaten out of me by game dev deadlines.

hooah
Feb 6, 2006
WTF?
I feel like I'm going insane. I'm working on cleaning up a text file, but Visual Studio's debugger can't find the drat file, even if I put a copy of it in every single loving folder in the project directory. Running the program normally from within VS (Debug -> Start without debugging) works fine. What am I not getting?

Gerblyn
Apr 4, 2007

"TO BATTLE!"
Fun Shoe

Zilla32167 posted:

So, the company I've learned C++ while working for had a "no templates or multiple inheritance" rule, and essentially hewed as close to C in memory management and types as possible. Now that I'm out, I'm trying to figure which of the modern stuff I'll need to know. I know I'll need to pick up STL, but what else should I be knowing?

Multiple Inheritance in C++ is pretty messy, and should be avoided if at all possible. You can get some really weird behavior with forward defines and casting and things. I mean it does work, and if you're careful you probably won't run into issues, but the few times I've used it in the past have ended in disaster with me swearing never to do it again.

Slurps Mad Rips
Jan 25, 2009

Bwaltow!

Gerblyn posted:

Multiple Inheritance in C++ is pretty messy, and should be avoided if at all possible. You can get some really weird behavior with forward defines and casting and things. I mean it does work, and if you're careful you probably won't run into issues, but the few times I've used it in the past have ended in disaster with me swearing never to do it again.

Multiple public inheritance can get messy. Multiple private inheritance is pretty hard to screw up.

Gerblyn
Apr 4, 2007

"TO BATTLE!"
Fun Shoe

SAHChandler posted:

Multiple public inheritance can get messy. Multiple private inheritance is pretty hard to screw up.

I'd find a way :v:

I'm sure there are good reasons to do it, but I personally find it simpler to just composite the object in rather than doing private inheritance.

VikingofRock
Aug 24, 2008




Zilla32167 posted:

So, the company I've learned C++ while working for had a "no templates or multiple inheritance" rule, and essentially hewed as close to C in memory management and types as possible. Now that I'm out, I'm trying to figure which of the modern stuff I'll need to know. I know I'll need to pick up STL, but what else should I be knowing?

In addition to what other people have said, <algorithm> contains a lot of neat and useful stuff. It's all stuff that you can implement yourself without too much difficulty, but using the STL algorithms adds a lot of clarity to your code.

Sex Bumbo
Aug 14, 2004
There's finally a <filesystem> library now in the tr2 (at least in visual studio) that I've used for some basic tools. I'm sure someone can tell me how terrible I am for using it but it I found it pretty easy and suitable.

I've also used <atomic> <condition_variable> <mutex> and <thread> and while I don't actually do anything cross platform, they're also simple to use. Atomic has some interesting parameters that would be important if I cared about other platforms.

<random> is better if you care about that sort of thing. With a few exceptions I feel like people are really hard on boring old lcg rand() though.

<regex> exists but I don't usually use regexes in C++.

Initializer lists and uniform initialization can help clean up your code a bit without much effort.

Adbot
ADBOT LOVES YOU

BigRedDot
Mar 6, 2008

Gerblyn posted:

I'd find a way :v:

I'm sure there are good reasons to do it, but I personally find it simpler to just composite the object in rather than doing private inheritance.

Private inheritance is really just an alternate spelling for composition.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply