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
ColdPie
Jun 9, 2006

Peanutmonger posted:

Simple makefile?! Maybe at first, but if you were really into it, you'd go all out and use autotools. Vim (especially with ctags/etc) and autotools make a fantastic development environment.

Do you have a good resource for more information on using autotools (esp. with vim)? I'd like to do something like that, but don't know where to start.

Adbot
ADBOT LOVES YOU

ColdPie
Jun 9, 2006

HB posted:

What about a project with 40 source files and multiple targets?

At some point you just want to let the computer take care of it.

Not to mention traversing directories and making makefiles for each directory. Eclipse does a pretty good job of making makefiles, in my opinion.

ColdPie
Jun 9, 2006

I have a question about inheritance in C++. The C++ FAQ says that inheritance is not for code re-use, but rather for polymorphism and other related features. This seems to conflict with the old "Shape" example (class Shape contains a Position method and related variables, Circle and Rectangle inherit from Shape and inherit this method and data, so more code re-use). Is using inheritance for this reason wrong? If so, why? What am I missing here?

ColdPie
Jun 9, 2006

JoeNotCharles posted:

The point is that Position and related variables logically belong to all the various subclasses of Shape. If you had a method that happened to be coded very similarly for Circles and Rectangles, but not for Squares, you wouldn't want to add a base class that both Circle and Rectangle inherit from but Square doesn't just to hold this method, because that would make no sense. You also wouldn't put the Circle and Rectangle version in the base class and then have Square override it, because the Circle and Rectangle version doesn't apply to all Shapes so it has no reason being in the base class. (You also wouldn't just duplicate the code in the two classes - make a standalone friend function that's called from both, or something.)

Oh, I get you. That makes sense. Thank you.

ColdPie
Jun 9, 2006

chris_bacon posted:

I'm working on a blackjack program for my c++ class, but I'm having trouble working with all the separate files. When I compile the driver program, I get:

code:
realgar% g++ driver.cpp
/tmp/ccVQ0FJW.o: In function `dealCards(Deck, SimplePlayer, Hand)':
driver.cpp:(.text+0xcc3): undefined reference to `SimplePlayer::expose(Card)'
driver.cpp:(.text+0xd39): undefined reference to `SimplePlayer::expose(Card)'
driver.cpp:(.text+0xd63): undefined reference to `SimplePlayer::expose(Card)'
collect2: ld returned 1 exit status
SimplePlayer is a class in I defined in a file called player.cpp, and I #included "player.cpp" so I'm not sure what the problem is here. Do I need to also define SimplePlayer in player.h ?

Never include .cpp files. The header files (.h) contain information about the class that other files need to know -- basically, what functions/members are a part of the class. The source files (.cpp) contain definitions for the functions. A simple example:

Player.h (lay out the interface)
code:
#ifndef PLAYER_H
#define PLAYER_H

class Player {
public:
    Player();
    virtual ~Player();

    void doSomething();

private:
    int aNumber;
};

#endif
Player.cpp (define the function implementations)
code:
#include "Player.h"

Player::Player()
{
    aNumber = 17;
}

Player::~Player(){}

void Player::doSomething()
{
    aNumber += 5;
}
Driver.cpp (use the interface laid out in Player.h)
code:
#include "Player.h"

int main(int argc, char** argv)
{
    Player player;
    player.doSomething();

    return 0;
}
Notice that Driver.cpp does not include Player.cpp, but rather Player.h. Player.h contains just the interface for the Player class, nothing more. The actual implementation is contained within Player.cpp, where it belongs. Driver.cpp doesn't care how Player is implemented; it only cares about which functions and members are contained within Player.

Once you start dealing with inlines and templated code, things will be a little more complicated. But at your level, the above holds true.

ColdPie fucked around with this message at 04:18 on Mar 22, 2008

ColdPie
Jun 9, 2006

Incoherence posted:

The easiest way to do what you're describing is to switch to Java.

This is true, actually, and something I hadn't thought of when I was trying to come up with a reply. Java's UI may be butt-ugly, but you'll only have to code it once no matter which platform you plan to run it on. Since it sounds like you're just playing around with programming basics with your friends, Java might be ideal. Plus, Java and C++ are similar enough that you can more or less transfer what you learn from one to the other freely, at least for the basic stuff.

ColdPie
Jun 9, 2006

BraggPxnk posted:

Ok, now I'm starting to get worried. I started compiling Qt at around 10 this morning and its still running at 7:30pm. Is this normal?

Is it actually doing anything? Check the command-line output, doing one action shouldn't take more than a minute so make sure lines are scrolling. According to a quick google, 2 hours on a Pentium 2 is considered "slower than normal," and others are reporting ~10 minute compile times.

ColdPie
Jun 9, 2006

Plastic Jesus posted:

I came across this a year or two ago:

This sounds sane to me, and it's something I always wondered about. But I never follow that rule for the following reason: how do you include types that are defined in other headers, in your header?

code:
//One.h

class One {
  int aMember;
};
code:
//Two.h

#include "One.h"

class Two {
  One anotherMember;
};
How can this situation be arranged so that Two.h does not include One.h, but the class Two still contains a member of type One?

Edit: #ifdefs truncated, but pretend they're there

ColdPie
Jun 9, 2006

Drx Capio posted:

"Reduce dependencies by forcing your user to have essentially the same number of includes, only spread across many files and much more difficult to maintain!"

What a great idea.

Yeah, not to mention they must be kept in a precise order. One.h must come before Two.h! Hope you don't forget!

Seems like a good idea on the surface, but yeah, that just doesn't work. Though it does seem like there should be a way to prevent this (actual picture from one of my recent projects).

ColdPie fucked around with this message at 05:22 on Mar 27, 2008

ColdPie
Jun 9, 2006

floWenoL posted:

You know what else probably seemed like a good idea on the surface? You uploading an 800kb png and thumbnailing it.

Fair enough. Linked it, if you want to take it out of your post.

tyrelhill posted:

Thats probably the most disorganized UML diagram I've ever seen.

Doxygen :toot: I just had it analyze my project out of curiosity and saw that monster pop up. I figure there should be a way to prevent that kind of thing but hey v:)v

ColdPie
Jun 9, 2006

floWenoL posted:

No programming language will ever prevent bad design. :colbert:

What would you suggest? It includes common utilities, constants, and structs that are used in a whole bunch of sources. What's the alternative? I'm seriously asking here, I would love to avoid that mess in future projects.

ColdPie
Jun 9, 2006

JoeNotCharles posted:

Is the mess causing any concrete problems? Makefiles slow due to dependency analysis, etc? If not, don't bother trying to avoid it - the compiler's perfectly capable of dealing with crap like that. It's not 1989 anymore.

Absolutely not, it works fine. It just feels messy and "bad designy" like he mentioned. If it's normal, all right, just doesn't seem like the best way to do things.

ColdPie
Jun 9, 2006

Scaevolus posted:

If you want something shinier, SDL is probably a better choice than GLUT.

I was also going to suggest SDL. It handles everything you need for media applications in a cross-platform manner. It has methods for handling input, audio, video, and even networking. All of its facilities are very low-level, but there are libraries that abstract it up further, as well as the ability to just use OpenGL. I personally use SDL with OpenGL for video and SDL_mixer for audio and handle input on my own. My games compile in any of the three major operating systems with no modifications and only one #if, so that's awful nice.

ColdPie
Jun 9, 2006

Zombywuf posted:

As avenging dentist pointed out, I'm a numpty. It was the assignment operator that was declared private. It looks like you can simply remove the line with the assignment as the commandMutex member will have already been constructed with the default constructor.

And it doesn't look like you need to, but if you have to pass constructor arguments to your CMutex, you can do it in the class's initializer list:
code:
YourClass::YourClass():
  commandMutex(some, constructor, arguments)
{
    //...body of constructor...
This of course applies for any classes you have in YourClass.

I always ignored initializer lists because they look ugly and are hard to read and maintain, but they provide some really critical features like the above and arguments to inherited classes' constructors.

ColdPie
Jun 9, 2006

Donald Duck posted:

Is there any good C IDEs for Linux? All I ever hear about is Visual Studio. At the moment I've been using Emacs for it but I was wondering if there was anything else

Check out this thread in SH/SC, it should answer your question.

ColdPie
Jun 9, 2006

ehnus posted:

Whose standard is that?

I've always seen structs typedef'd either like that (append _t), or with an underscore on either side of the struct name. I think it's just the defacto standard, like using i and j for index variables. No one's going to eviscerate you for not using it, but it's just what "usually" is used.

ColdPie
Jun 9, 2006

6174 posted:

I've got a template question. I have two functions:
code:
template<class T>
vector<T> arbitrary_partition(T number, vector<T> partite_sizes);

template<class T>
T arbitrary_partition(T number, vector<T> partite_sizes);

Your trouble is right at the start. These two functions have the same signature: arbitrary_partition(T, vector<T>). There's no way for the compiler to distinguish between them. You'll either need to give the functions different names, or change the parameters they accept.

ColdPie
Jun 9, 2006

notMordecai posted:

I have a Data Structures final today (in about 4 hours) and I am trying to get the gist of what everything is about. One of the big problems I had this semester was trying to wrap my head around Recursion. I had this example question for a review:

Q: Write a recursive function for f(x) = f(x-1) + 4x + 3 where f(0) = 1.

Is this correct?

Just kind of at a first glance (about to run out the door to school myself), this looks all right. I'd add in a check to make sure x isn't negative -- that'd create an infinite loop. Depending on exactly how the requirements are worded, I'd throw the check for <=0 at the start:

code:
int recursive(int x){
  if( x <= 0 )
    return 1;
  else
    return (/*blah blah*/);
}
This will return 1 on an invalid (negative) number, though maybe the assignment calls for an exception to be thrown or something.

Anyways looks fine to me. Good luck.

ColdPie
Jun 9, 2006

Looks like the posters above fixed you, but I'll mention a couple things I noticed.

On line 44 you're using the value "10000" instead of your constant NUM_TRIALS. Not an error, but could be if you changed the constant and forgot to update that number.

The if statement on line 72 doesn't have brackets, so only the first statement following it is affected by the if. You've got two lines indented there, so I'm not sure if you meant for both of those lines to be in the if's body.

ColdPie
Jun 9, 2006

Zaxxon posted:

here's something that has been bothering me for a while and is pretty stupid, but I wonder if there is something else I'm not thinking about.


I use "int* Foo" for that exact reason. It's terrible style to declare several variables on one line anyway, so I think this is actually more clear than the "correct" way to do it.

ColdPie
Jun 9, 2006

HB posted:

vvvvvvvv Considering the subject, your analogy should be reversed :v:

Boz0r posted:

With admin access. I'm just trying to kill my dell.

Could you give me a little more in-depth hint? I'm not too hot on C++ yet.

Please don't futurequote, it makes threads hell to read. :)

ColdPie
Jun 9, 2006

Lexical Unit posted:

At my job I always see this sort of thing:

code:
enum Directions
{
  eNorth, eSouth, eWest, eEast, ..., 
  kNumDirections
};
Not sure how I feel about it.

I use that all the time and see no reason why it would be considered bad practice given that the first enum is explicitly defined to be 0 (or is that actually part of the standard?). It's pretty obvious what's going on and completely removes the maintenance for keeping track of the number of elements.

ColdPie
Jun 9, 2006

While reading through the Qt documentation the other day, I noticed that they use a simple strategy to get around the include file mess that we talked about that in here a few months ago. I don't remember seeing it mentioned when we talked about this, and it seems like a pretty nice solution.

code:
/*SomeClass.h*/
#ifndef SomeClass_h
#define SomeClass_h

class SomeClass
{
public:
  SomeClass(int blah);
  //whatever...
};

#endif
code:
/*Another.h*/
#ifndef Another_h
#define Another_h

//note that there's no include, we just say "this
//class exists," kind of like a function prototype
class SomeClass; 

class Another
{
public:
  Another();
  SomeClass someClass;
  //whatever...
};

#endif
code:
/*Another.cpp*/
#include "Another.h"

//here's where we include the actual header
#include "SomeClass.h"

Another::Another():
  someClass(17)
{
  //whatever...
}

//implement functions, etc.
I've never seen this strategy used before -- is there a disadvantage to it? Using this strategy, changing SomeClass.h won't cause everything that depends on Another.h to recompile, which is what I considred to be the major problem with the "include mess."

ColdPie fucked around with this message at 05:12 on Jun 12, 2008

ColdPie
Jun 9, 2006

I see, thanks for the tip. Hopefully someone in here hasn't seen it before and thinks it's as awesome as I do :)

ColdPie
Jun 9, 2006

I've got what feels like a really dumb question.

If I've got a class member and I want to pass certain values to its constructor, but can't use in the initialization list, do I have to use a pointer? See simple example:

code:
class Game {
public:
  Game();

private:
  World* world;
}

Game::Game(){
  SomeObj obj;
  world = new World(obj); //<--
}
The pointed-to line is where I want to construct world. Must world be a pointer to accomplish this? Obviously I could just instantiate obj in the initialization list in this example, but that has a bunch of obvious limitations.

Is there a better way to do this?

ColdPie
Jun 9, 2006

GrumpyDoctor posted:

You can just make it not a pointer and remove the new.

World doesn't have a default constructor, so I'd have to provide some bogus arguments in the initializer list, which could cause problems. Also, if a default constructor did exist, wouldn't that invoke a copy operation and trash the temporary object (very inefficient)?

Adbot
ADBOT LOVES YOU

ColdPie
Jun 9, 2006

Keep the trolling in YOSPOS please.

GrumpyDoctor posted:

My gut response is "so give it a default constructor." I'm sure that doesn't say anything good about me. What problems would that cause?

And yes, it's "inefficient," but are you spending a lot of time constructing Game objects?

Well, World isn't my class, it's part of a physics library I'm playing with. And even so, that seems more like a workaround than a general solution. What if I had a similar situation for something that was very expensive to copy (or even couldn't be copied for some reason) or I had to do a ton of these initializations?

It seems like there should be a better way to arrange my classes to fix this problem or something. It's obvious why you can't "delay" construction of the World object, but I can't think of a better way to set stuff up to avoid using the heap.

I guess there's no reason to avoid the heap, it just feels "incorrect" to dynamically allocate an object that will never be recreated during the lifetime of the program.

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