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
Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
What does an abstract class with no public interface give you over just not inheriting at all? void doStuff(VehicleDealership vd) { ... } can't actually do anything with vd.

floWenoL posted:

What if someone has a PorscheDealership but add()s a non-Porsche car?

It'd fail to compile because there is no add(Car *)?

Adbot
ADBOT LOVES YOU

awesmoe
Nov 30, 2005

Pillbug
awesmoe@batman:~$ cat test.cc
pre:
class Foo {
    int i;
    };

int main(int argc, char** argv){
    Foo* foo = dynamic_cast<Foo*>(foo); // 1
    int i = i;                          // 2
}
awesmoe@batman:~$ g++ -Wall -pedantic test.cc -o lmao
awesmoe@batman:~$


Is anyone else surprised that neither of the lines in main give at least warnings?
Is this a bug in g++ or is it standard behaviour, and if it's standard can anyone give me insight into why it was decided upon?

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

awesmoe posted:

Is anyone else surprised that neither of the lines in main give at least warnings?
Is this a bug in g++ or is it standard behaviour, and if it's standard can anyone give me insight into why it was decided upon?

Why would you think that's a bug in the compiler and not your code?

Incidentally, you want -Winit-self

Avenging Dentist fucked around with this message at 04:19 on Feb 13, 2009

floWenoL
Oct 23, 2002

Plorkyeran posted:

It'd fail to compile because there is no add(Car *)?

Well, I meant addCar() but looks like that's protected. I guess by "pure virtual" ThugBonnet meant that base classes wouldn't have any methods at all, which is pretty useless, then.

awesmoe
Nov 30, 2005

Pillbug

Avenging Dentist posted:

Why would you think that's a bug in the compiler and not your code?
I mean bug in the compiler to accept that code. As I see it, that code shouldn't compile. Is there a specific legitimate case where someone would use that construct (necessitating compilers accepting it) , or is it just one of those bugs that the compiler doesn't warn you about?

ed: Still nothing with -Winit-self

awesmoe fucked around with this message at 04:24 on Feb 13, 2009

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

awesmoe posted:

I mean bug in the compiler to accept that code. As I see it, that code shouldn't compile. Is there a specific legitimate case where someone would use that construct (necessitating compilers accepting it) , or is it just one of those bugs that the compiler doesn't warn you about?

Avenging Dentist posted:

Incidentally, you want -Winit-self

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

awesmoe posted:

ed: Still nothing with -Winit-self

That might be a bug, but -Wall -O should trigger it via -Wuninitialized, which can only be enabled when -O is on (or its friends). Technically, you also want -Winit-self but it seems to fire anyway. Most of this is in the docs, by the way.

Avenging Dentist fucked around with this message at 04:35 on Feb 13, 2009

Thug Bonnet
Sep 22, 2004

anime tits ftw

Plorkyeran posted:

What does an abstract class with no public interface give you over just not inheriting at all? void doStuff(VehicleDealership vd) { ... } can't actually do anything with vd.


It'd fail to compile because there is no add(Car *)?

In practice there would be public interfaces for the base classes, sorry that wasn't clear, I was just illustrating the hierarchy. And it's okay if the lists in the base classes are out of sync with one another. For example, there could be a GermanCarDealership which inherits from both PorscheDealership and VolkswagenDealership, in which case the list of Car* in CarDealership will have more elements than either the list of Porsche* in PorscheDealership or the list of Volkswagen* in VolkswagenDealership. Because of this we can safely call public methods at any level of specificity (Vehicle, Car, Porsche, Volkswagen) without casting, we can enumerate our Porsche*s without a dynamic_cast, etc.

As far as how this is important to my GamePresenter and GameView, they inherit from Observer and Subject respectively. I would like those two base classes to handle everything that needs to be done for the Observer-Subject relationship: Subjects may be observed by any number of Observers, and handle the basic methods they call on one another for basic messaging and registration. But in certain cases I would like to prevent some specific couplings of Observer-Subject in cases where it wouldn't make any sense, and do so without relying on RTTI. It wouldn't make much sense for a GamePresenter to observe a WindowView, for example.

Thug Bonnet fucked around with this message at 05:44 on Feb 13, 2009

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Like I said a long time ago, use templates.

TSDK
Nov 24, 2003

I got a wooden uploading this one

Thug Bonnet posted:

Lots of problems
Your root problem is that you're trying to apply real-world intuition about the relationships between different objects to class design and inheritance. Just because a Car is-a type of Vehicle in the real world, it doesn't hold that mirroring this directly into a class hierarchy will result in a good (or even workable) design for what you're trying to write. This holds just as true for GamePresenter etc...

Read through this (21.6 through to 21.11):
http://www.parashift.com/c++-faq-lite/proper-inheritance.html
and make sure you understand the substitution principle of inheritance before proceeding.

Thug Bonnet
Sep 22, 2004

anime tits ftw

TSDK posted:

Your root problem is that you're trying to apply real-world intuition about the relationships between different objects to class design and inheritance. Just because a Car is-a type of Vehicle in the real world, it doesn't hold that mirroring this directly into a class hierarchy will result in a good (or even workable) design for what you're trying to write. This holds just as true for GamePresenter etc...

Read through this (21.6 through to 21.11):
http://www.parashift.com/c++-faq-lite/proper-inheritance.html
and make sure you understand the substitution principle of inheritance before proceeding.

I thought I had a pretty-good handle on the is-a problem, especially with regard to the circle/ellipse example. Even given the circle/ellipse example it would seem that as far as a hierarchy goes that you can use Vehicle->Car without too much problem, as long as you don't assume anything in Vehicle that may dilute Car. You wouldn't want an openDoor() method in Vehicle, for example, since lots of vehicles don't have doors.

What about the Vehicle->Car (or GameView-GamePresenter) relationship do you feel is inherently improper?

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.

awesmoe posted:

I mean bug in the compiler to accept that code. As I see it, that code shouldn't compile. Is there a specific legitimate case where someone would use that construct (necessitating compilers accepting it) , or is it just one of those bugs that the compiler doesn't warn you about?
As soon as you declare a variable it can be used in any in-scope expression, including initialization expressions. E.g.
code:
int x = 4, y = x, z = f(y), q = q;
q = q;
It's not a bug or special case.

Mustach fucked around with this message at 16:30 on Feb 13, 2009

Pooball
Sep 21, 2005
Warm and squishy.

awesmoe posted:

I mean bug in the compiler to accept that code. As I see it, that code shouldn't compile. Is there a specific legitimate case where someone would use that construct (necessitating compilers accepting it) , or is it just one of those bugs that the compiler doesn't warn you about?

ed: Still nothing with -Winit-self

I could try to think up an example where "void *x = &x;" is useful. Since compilers have to allow "&x" on the right hand side they might as well allow "x".

Specifically using the value of x in the definition of x? You're asking for an example of code that makes use of uninitialized values, and undefined values are useless (except perhaps as entropy).

But imagine a code generator that sometimes writes "int a = a;" and never uses "a". Perhaps this makes the code generator cleaner. Thanks to the standard, a conforming compiler is able to handle this code. It is much nicer to have a compiler that sticks to a standard and gives optional warnings on human-readable code.

TSDK
Nov 24, 2003

I got a wooden uploading this one

Thug Bonnet posted:

What about the Vehicle->Car (or GameView-GamePresenter) relationship do you feel is inherently improper?
There's nothing inherently wrong with the Vehicle->Car relationship in isolation, because there's no actual interface there.

However, the substitution principle says that wherever you have a Base *, then it must be acceptable to pass a Derived *. The container classes are heading towards breaking that principle, and everything else from then on is just a sticking plaster.

Given the Car/Dealer scenario you've outlined, a better design would be to use data rather than classes to drive the behaviour. So you have a single Vehicle class with a type ID (possibly an enum), and the Dealer class then has a member saying which type ID (or IDs) is acceptable to be stored in the container.

This is effectively boils down to manually doing what the dynamic_cast testing would be doing anyway, but it's a lot less code to add a new type ID than it is to add in a new derived class, and you're making it much more explicit what's actually going on.

Thug Bonnet
Sep 22, 2004

anime tits ftw

TSDK posted:

However, the substitution principle says that wherever you have a Base *, then it must be acceptable to pass a Derived *. The container classes are heading towards breaking that principle, and everything else from then on is just a sticking plaster.

That's what I was working toward, the multiple lists is just to prevent casting up, or using an enum, but I'll look at enums again and see if it makes more sense to me having re-read the faq-lite OO section.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
You shouldn't need to use enums here; it should be perfectly possible to do this in a type-safe manner. However, you will need to convince yourself that there are two valid but different kinds of polymorphism, and that this case requires both.

Let's go back to your dealership scenario. You've got vehicle dealerships, car dealerships, and Porsche dealerships, and you think you want them to be related in a chain of subtypes. That's not inherently unreasonable, but it really comes down to your definitions, so let's look at those a little.

What is a vehicle dealership? It's a place where you buy and sell vehicles, right? Well, we could define it that way: "a vehicle dealership is a place where you can buy and sell any kind of vehicle." Now, under this definition, is a Porsche dealership a vehicle dealership? No, it isn't — a Porsche dealership lets you buy and sell one particular kind of vehicle, not arbitrary vehicles.

So if our definition doesn't work for what we want to do, let's find a better one. "A vehicle dealership is a place where you can buy and sell a particular kind of vehicle." That's an example of "parametric polymorphism"; now we can't just talk about dealerships, we have to say what kind of things the dealership trades in. So a vehicle dealership is a dealership that trades in (some type of vehicle), and a car dealership trades in (some kind of car), and a Porsche dealership trades specifically in Porsches.

In C++, you use templates to express parametric polymorphism; unfortunately, the type system is (currently) not sophisticated enough (I think) to statically check quite everything you want to check. So you can write this:

code:
template <class T> class Dealership {};
template <class T> class CarDealership : public Dealership<T> {};
class PorscheDealership : public CarDealership<Porsche> {};
...and unfortunately there's no way of expressing that the parameter type T to CarDealership has to be a subtype of Car. If we add methods to CarDealership which fetch T objects and assume they're cars, then those methods will probably fail to compile if T is the wrong type — but that can be a somewhat confusing source of error.

awesmoe
Nov 30, 2005

Pillbug
Thanks for the replies, guys - I'm still surprised that int i(i); works, but I can understand the other cases. I don't understand order of execution in construction very well at any rate (as demonstrated here!), so thanks for the help.

Incidentally -Winit-self was only added in gcc 4.0, and I was using 3.2.3 when I found the actual error in the code. So I guess I wasn't the only one who thought a warning should be added for that case :)

And AD - the reason I specifically asked here rather than just googling 'assignment during initialization' was because I'm pretty sure there's some idea that I'm missing here, and I thought that a dialogue would let me get a clearer picture of what it is than just a wall of text.

That Turkey Story
Mar 30, 2003

rjmccall posted:

In C++, you use templates to express parametric polymorphism; unfortunately, the type system is (currently) not sophisticated enough (I think) to statically check quite everything you want to check.

...and unfortunately there's no way of expressing that the parameter type T to CarDealership has to be a subtype of Car. If we add methods to CarDealership which fetch T objects and assume they're cars, then those methods will probably fail to compile if T is the wrong type — but that can be a somewhat confusing source of error.

You can with the power of SFINAE (or in C++0x with concepts)! With boost this can be done with Boost.TypeTraits and enable_if:

code:
template< typename T, typename Enabler = void >
class CarDealership;

template< typename T >
class CarDealership< T, typename enable_if< is_convertible< T*, Car* > >::type >
{
  // Definition here
};

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Yeah, that's why I qualified that first statement. I should've known that one, though.

POKEMAN SAM
Jul 8, 2004

That Turkey Story posted:

You can with the power of SFINAE (or in C++0x with concepts)! With boost this can be done with Boost.TypeTraits and enable_if:

code:
template< typename T, typename Enabler = void >
class CarDealership;

template< typename T >
class CarDealership< T, typename enable_if< is_convertible< T*, Car* > >::type >
{
  // Definition here
};

haha, "is_convertible" for cars

That Turkey Story
Mar 30, 2003

Ugg boots posted:

haha, "is_convertible" for cars

:doh:

Contero
Mar 28, 2004

Quick question, is it possible to make a non-member operator[] function?

code:
(inside class declaration)
   struct Piece {
      Piece () : loc(-1, -1) {}
      Piece (int row, int col, Color color = kEmpty, Type type = kNormal) :
       loc(row, col), color(color),  type(type) {}
      std::pair<short,short> loc;
      Type type;
      Color color;
   };

   friend Piece &operator[] (Piece (&board)[kWidth][kWidth]), const std::pair<short, short> &loc)
    {return board[loc.first][loc.second];}
I get error C2801: 'operator []' must be a non-static member.

What I want to be able to do is index a two dimensional array using a pair instead of having to drag out .first and .second, like this:

code:
Piece board[kWidth][kWidth];
std::pair<short, short> spot(5,6);

board[spot].doSomething(); // this instead of
board[spot.first][spot.second].doSomething();
Is this possible?

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
No.

Contero
Mar 28, 2004

Actually I just thought about it for a second and did this, which works I guess:

code:
   struct Board {
      Board () {}
      Piece pieces[kWidth][kWidth];
      Piece &operator[] (const std::pair<short, short> &loc)
       {return pieces[loc.first][loc.second];}
   };

darfur
Nov 1, 2003
There are a thousands of posts in this thread and search is not available at the moment, so forgive me if this something covered a lot.

I have a pgina dll that's used at work. I'm trying to add functionality to it so that a remote system can instruct different computers to do things (computer lab setting, so the lab attendant can log many stations in without having to do them all individually, stuff like that). I would think this would be possible by setting up a thread in the dll which listens for instructions over the network. I have a stand alone program which correctly accepts instructions from the network and does the appropriate actions, but when i throw that code into the dll project (vc++), my server thread gets as far as the accept() function from winsock2.h.
code:
hClientSocket = accept(hSocket, 0, 0);
MessageBox(0, 0, 0, 0);
The thread just seemingly gets swallowed up by that function and ceases to exist (or execute at least). The MessageBox never shows, and it doesn't throw an exception.

There is existing code in the dll which sends commands/requests out over the network using winsock2, and I have made sure that my server is running on a different port than those commands (unrelated to the functionality i'm trying to add).

I don't plan on posting more code since it works outside of the dll, I'm just not sure what to look for inside of the dll to see what could be messing it up. Any suggestions what I could look for, what things may cause that accept call to fail without any errors being thrown? Or do I need to post more code?

Cirrus_Alreia
Oct 26, 2007
Count Chocula Incarnate
Alright so, I have a serious issue which is bugging me and I can't find the answer.I have a function in a class that when it is called sets a flag to 'true' and sets a pointer in the object calling the function equal to the object passed into it. The only issue is, is that after the function that sets the pointer is called the objects destructor is called and my pointer is deleted.

Any ideas as to what is causing this?

Vanadium
Jan 8, 2005

You are passing something by value instead of by reference?

Cirrus_Alreia
Oct 26, 2007
Count Chocula Incarnate

Vanadium posted:

You are passing something by value instead of by reference?

nope, it is passed by reference
code:
void CTrafficLight::setptr(CTrafficLight& B)
{
	m_coned = &B;
}
//m_coned is a pointer of CTrafficLight type.
Holy hell, thank you. The original function was passed by value. I didn't even think about that.

Cirrus_Alreia fucked around with this message at 12:21 on Feb 16, 2009

sonic bed head
Dec 18, 2003

this is naturual, baby!
Is there anything in C++ that is like a php string-indexed array or javascript object or dictionary thing? I am taking my first C++ class and I've been asked to do one of 5 different things based on a string input. I know that I can't dynamically choose a function based on a string, but since there's no in_array function in C++ I can't think of how to validate the input without writing a lot of if's.

Basically I'm trying to do this in java script:

code:
var options = ["first","second","third","fourth","fifth"]
var input = getInput();
if(options.indexOf(input) == -1){
alert("your input is invalid);
}
else{
//proceed with functionality based in value in input
}
What is the best practice for doing something like this? Should I really be writing, if(input != "first && input !="second" &&..)?

Thanks.

shrughes
Oct 11, 2008

(call/cc call/cc)

sonic bed head posted:

Is there anything in C++ that is like a php string-indexed array or javascript object or dictionary thing?

That would be a std::map<std::string, T>.

code:
map<string, int> foo;
foo["hello"] = 3;
foo["hey"] = 5;
int bar = foo["hello"];
If I wanted to have some options and respond based on the option, I'd typically want to use something like a map<string, Something> where the Somethings provide a method to perform the appropriate action, but that's because I'm used to C# where that's doable without any sort of hassle.

shrughes fucked around with this message at 19:25 on Feb 16, 2009

Contero
Mar 28, 2004

Is there some sort of built in profiler for VS 2005? I can't seem to get gprof working at the moment and figured now is as good a time as any to learn how to use a new tool.

Dijkstracula
Mar 18, 2003

You can't spell 'vector field' without me, Professor!

shrughes posted:

That would be a std::map<std::string, T>.
Indeed, but if this is an assignment, going overboard with STL containers and other stuff that he's guaranteed to not have been taught will probably not result in him getting a good grade.

raminasi
Jan 25, 2005

a last drink with no ice

Contero posted:

Is there some sort of built in profiler for VS 2005? I can't seem to get gprof working at the moment and figured now is as good a time as any to learn how to use a new tool.

There is, but only in the Team Edition.

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip

Dijkstracula posted:

Indeed, but if this is an assignment, going overboard with STL containers and other stuff that he's guaranteed to not have been taught will probably not result in him getting a good grade.

A real real easy way to know this for sure is to just email a TA and ask if you can use poo poo:eng101:

spiritual bypass
Feb 19, 2008

Grimey Drawer

Otto Skorzeny posted:

A real real easy way to know this for sure is to just email a TA and ask if you can use poo poo:eng101:

Easier to ask forgiveness than permission!

Lexical Unit
Sep 16, 2003

sonic bed head posted:

I am taking my first C++ class and I've been asked to do one of 5 different things based on a string input.
Since you have to branch based on user input anyway, you might as well just do a if ... else if ... else with the final else just printing out "sorry that's not a valid input." That's probably the intended solution to the assignment anyway.

sonic bed head posted:

I know that I can't dynamically choose a function based on a string
Sure you can, there are lots of ways. For example the solution I described above could choose a function based on user input.

sonic bed head posted:

but since there's no in_array function in C++ I can't think of how to validate the input without writing a lot of if's.
There's no in_array() function, but there is find() which you can use to similar effect. Here is your javascript translated very literally into C++:
code:
#include <algorithm>
#include <iostream>
#include <string>

using namespace std;

int main() {
	string options[] = { "first", "second", "third", "fourth", "fifth" };
	size_t n = 5;

	string input;
	getline (cin, input);
	
	if (find (options, options + n, input) == options + n)
		cerr << "your input is invalid" << endl;
	else
		cout << "your input is valid" << endl;
}
I wouldn't recommend a solution like that though. For one because it's ugly and for two because ...

sonic bed head posted:

What is the best practice for doing something like this? Should I really be writing, if(input != "first && input !="second" &&..)?

I'd imagine the easiest thing to do would be to have some kind of lookup table mapping user input to actions. There are lots of different ways you could do this, and many different libraries you could leverage to accomplish it. But for a simple class assignment a few ifs is probably good enough.

You don't absolutely need to do like you suggested though: "if(input != "first && input !="second" &&..)" is a bit overkill. You could simply have the final else catch all invalid input.

Contero
Mar 28, 2004

GrumpyDoctor posted:

There is, but only in the Team Edition.

:wtc: Well at least I got gprof working.

more falafel please
Feb 26, 2005

forums poster

In MSVC, is there a way to tell if you're running in the debugger?

On a related note, why would an app take ~5 times as long to load in the debugger as outside it?

csammis
Aug 26, 2003

Mental Institution

more falafel please posted:

On a related note, why would an app take ~5 times as long to load in the debugger as outside it?

It might have something to do with the debugger attempting to load symbols for every module loaded by your application, which of course would not happen outside the debug environment. If you're set up to pull Windows symbols from the Microsoft symbol servers automatically instead of on-demand, that process can take a really long time.

Adbot
ADBOT LOVES YOU

POKEMAN SAM
Jul 8, 2004

csammis posted:

If you're set up to pull Windows symbols from the Microsoft symbol servers automatically instead of on-demand, that process can take a really long time.

This means you've debugged WPF applications before!

</offtopic>

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