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
raminasi
Jan 25, 2005

a last drink with no ice

TasteMyHouse posted:

The way I understand it, use a shared_ptr unless doing so would cause a cyclic reference, in which case use a weak_ptr -- but I'm actually not sure what you think isn't clear cut about passing a smart pointer into a function and I'm curious to hear you elaborate.

I guess I'm just not really sure whether, in practice, accidental cyclic references happen often enough to justify not using shared_ptrs by default.

Adbot
ADBOT LOVES YOU

shrughes
Oct 11, 2008

(call/cc call/cc)

GrumpyDoctor posted:

When using (TR1) smart pointers, which is a better rule of thumb: use shared_ptrs unless you have a reason not to, or use weak_ptrs unless you have a reason not to?

My rule of thumb is to use a scoped_ptr whenever you want and avoid shared_ptrs like the plague, because the last thing we want is to have something destroyed on the wrong thread, so what's the point of shared_ptrs? Also shared_ptrs have a high overhead and if you want to share your pointers, use intrusive_ptr.

But we aren't you and your needs are different.

Dren
Jan 5, 2001

Pillbug
Say you have some function:
code:
void doStuff(void *&memory);
Can any good come of this? It seems like a memory management nightmare waiting to happen.

Here's a blog post about passing pointers by reference in case you are unfamiliar with the syntax.
http://markgodwin.blogspot.com/2009/08/c-reference-to-pointer.html

shrughes
Oct 11, 2008

(call/cc call/cc)

Dren posted:

Say you have some function:
code:
void doStuff(void *&memory);
Can any good come of this?

No, void doStuff(void **memory) is the sane way to do this. Personally I have an idiomatic and inscrutable method for distinguishing between when it's appropriate to pass by reference and to pass a pointer.

wellwhoopdedooo
Nov 23, 2007

Pound Trooper!

Dren posted:

Say you have some function:
code:
void doStuff(void *&memory);
Can any good come of this? It seems like a memory management nightmare waiting to happen.

Here's a blog post about passing pointers by reference in case you are unfamiliar with the syntax.
http://markgodwin.blogspot.com/2009/08/c-reference-to-pointer.html


I don't really see a problem with it, although I'd be more inclined to do this:

code:
void* doStuff(void* const memory);
Maybe some crazy-rear end optimization would make it worthwhile, but otherwise it just looks designed to confuse. As for it being a memory-management nightmare, it's taking a pointer and returning a (probably [but you'd better not assume definitely]) different pointer. It's going to be a nightmare no matter what you do with the signature.

shrughes
Oct 11, 2008

(call/cc call/cc)

wellwhoopdedooo posted:

I don't really see a problem with it, although I'd be more inclined to do this:

code:
void* doStuff(void* const memory);
Maybe some crazy-rear end optimization would make it worthwhile, but otherwise it just looks designed to confuse.

That's worse because that makes it more likely for the API to be misused. The former technique of void*& or void** is a way of implying to people using the function that the old pointer value is to be discarded and thou shalt never use it thygain.

Alters
Mar 4, 2010

I need to append two int's together not in the sense of 1 + 2 = 3 but as 1 + 2 = 12. I know how to do this with strings but is there an easy way to do it with int's?

I tried googling this but I can't find the proper way to word it.

shrughes
Oct 11, 2008

(call/cc call/cc)

Alters posted:

I need to append two int's together not in the sense of 1 + 2 = 3 but as 1 + 2 = 12. I know how to do this with strings but is there an easy way to do it with int's?

I tried googling this but I can't find the proper way to word it.

Convert them to strings, concatenate them, convert back to integer.

Edit: std::stringstream s; s << 1 << 2; std::string t = s.str();

shrughes fucked around with this message at 01:39 on Aug 11, 2011

Cubiks
Aug 31, 2005
I wish I had something witty to put here...

shrughes posted:

Convert them to strings, concatenate them, convert back to integer.

Edit: std::stringstream s; s << 1 << 2; std::string t = s.str();

Or, you know, just use math:

code:
int n1=1;
int n2=2;

int concat = 10*n1+n2;
Edit: VVVV Ah, thought I was overlooking something silly. Yeah, have to be a bit smarter if n2 > 9.

Cubiks fucked around with this message at 04:45 on Aug 11, 2011

shrughes
Oct 11, 2008

(call/cc call/cc)

Cubiks posted:

Or, you know, just use math:

code:
int n1=1;
int n2=2;

int concat = 10*n1+n2;

But first you have to compute the log10 of the number.

Alters
Mar 4, 2010

Cubiks posted:

Or, you know, just use math:

code:
int n1=1;
int n2=2;

int concat = 10*n1+n2;

Don't think that would work if n2 was 10 or higher but in my case it's only 0-9 so that works perfectly.

Thanks for the help guys. I should have stated that the number being added to the first one will never be greater than 9.

Alters fucked around with this message at 02:26 on Aug 11, 2011

Oxyclean
Sep 23, 2007


I've been giving a polymorphic class:

code:
class Course
{
	double m_fee;
public:
	Course(double=0.0);
	Course(Course&);
	virtual~Course();
	bool operator>(Course&);
	bool operator<(Course&);
	virtual void Report()=0;
};
with a subclass:
code:

class FullTimeCourse: public Course
{
	char m_id[30];
public:
	FullTimeCourse(double=0.0,char* = "");
	FullTimeCourse(FullTimeCourse&);
	~FullTimeCourse();
	void Report();
};
How am I supposed to access m_fee? it's private to Course, but every course needs to have a fee and id.
Right now I'm using the subclasses constructor like this:

Course * ftc = new FullTimeCourse(fee,courseid);

But the the fee can't be set from within the subclass because it's private to course. I'm not allowed to change the implementation of this either. Nor can the report function access that fee.

shrughes
Oct 11, 2008

(call/cc call/cc)

Oxyclean posted:

How am I supposed to access m_fee? it's private to Course, but every course needs to have a fee and id.

You can either have a function on the base class that accesses it for your subclass, or you can make the field protected.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
The way you would set it is to make your constructor pass the value down to the base class constructor. You do that by naming the base class in the base/member initializers list:

code:
class Animal {
protected:
  Animal(Coloring color, int numLegs);
};

class Bear : public Animal {
public:
  enum Kind { AmericanBlack, AsianBlack, Brown, GiantPanda, Polar, Spectacled, Sloth, Sun };
  static Coloring getColoringForKind(Kind k);
private:
  BearKind _kind;
protected:
  Bear(BearKind kind) : Animal(getColoringForKind(kind), 4), _kind(kind) {
    // more initialization code goes here if necessary
  }
};
But yeah, there's no legitimate way to actually read it given that class signature, so tough luck there.

Oxyclean
Sep 23, 2007


e: Nm, figured it out; had to put the ": Course(fee)" after my constructor in the subclass

e: Of course someone responds just as I fix my mistake, haha.

Thanks much though.

Oxyclean fucked around with this message at 05:47 on Aug 11, 2011

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
He's actually talking about the initializer list on the constructor itself. The relevant line in the example:

code:
Bear(BearKind kind) : Animal(getColoringForKind(kind), 4), _kind(kind) {
Note how the Bear(BearKind) constructor is passing getColoringForKind(kind) through to the Animal constructor - you're going to want to do something similar with passing the fee through.

Gerblyn
Apr 4, 2007

"TO BATTLE!"
Fun Shoe

Hughlander posted:

Visual Studio question...

I open up a vcproj file and see:

code:
    <Tool
        Name="VCCLCompilerTool"
        PreprocessorDefinitions="_Foo=Blah"
    />
However, when I browser the properties from within dev studio, I don't see /D_Foo=Blah in the command line generated nor in any of the options in dialog.

Is there a way to see/set this from within Dev Studio?

In Visual Studio .NET, you go to the properties page of the project, then:

C/C++ -> Preprocessor -> Preprocessor Definitions

I think you're using VS2008? It's been years since I used that version, but I believe it's in the same place...

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

rjmccall posted:

But yeah, there's no legitimate way to actually read it given that class signature, so tough luck there.
You can do a binary search for it :v:

TasteMyHouse
Dec 21, 2006

Plorkyeran posted:

You can do a binary search for it :v:

assuming that's how operator< and operator> are defined ;).

If you knew how the compiler laid out the object you could do some aliasing magic to read it.

Oxyclean
Sep 23, 2007


I'm told that the pure virtual function of the parent class (Course) can have a body and access m_fee.

How would I then use that?

From the subclass:
code:
void Course::Report() : Report() {
}
Doesn't work like the way I used the parent class constructor.

Oxyclean fucked around with this message at 16:15 on Aug 11, 2011

Dren
Jan 5, 2001

Pillbug

shrughes posted:

No, void doStuff(void **memory) is the sane way to do this. Personally I have an idiomatic and inscrutable method for distinguishing between when it's appropriate to pass by reference and to pass a pointer.
I much prefer that style. Having never seen void *& in an arglist before caused me to forget my rule that parameters passed by reference should always be passed as pointers (*) and not as references (&) so that the calling code must be explicit about passing by reference.

i.e.
code:
void somefunc(int *a);

main()
{
  int a = 5;
  somefunc(&a);
}
versus
code:
void somefunc(int &a);

main()
{
  int a = 5;
  somefunc(a);
}
The former is clearer about modification of memory in the calling context than the latter.

Anyway, using a void *& argument seems inadvisable in C++ since it's probably eating memory and spitting memory back out and C++ has safer ways of dealing with memory.

Dren
Jan 5, 2001

Pillbug

Oxyclean posted:

I'm told that the pure virtual function of the parent class (Course) can have a body and access m_fee.

How would I then use that?

From the subclass:
code:
void Course::Report() : Report() {
}
Doesn't work like the way I used the parent class constructor.

You can't use an initializer list for anything but a constructor.

You can, however, define a function body for Course's Report method. So you define:
code:
void Course::Report()
{
    std::cout << m_fee << std::endl;
}
Now you need to know about the virtual keyword. FullTimeCourse's Report method isn't virtual and that will be a problem for you. However, given a FullTimeCourse object you will be able to access Course's report method. Go go google.

Gerblyn
Apr 4, 2007

"TO BATTLE!"
Fun Shoe

Oxyclean posted:

I'm told that the pure virtual function of the parent class (Course) can have a body and access m_fee.

How would I then use that?

From the subclass:
code:
void Course::Report() : Report() {
}
Doesn't work like the way I used the parent class constructor.


But if it has a body, then it's not pure, virtual :confused: Are you sure your instructor isn't just loving with you?

Anyways, you can do something like this:

code:

class Course
{
private:
  int m_free;
public:
  virtual void Report();
};

void Course::Report()
{
  cout << "Fee is " << m_fee << "\n";
}

class FullCourse : public Course
{
private:
  int m_num_chickens;
public:
  virtual void Report();
};

void FullCourse::Report()
{
  Course::Report();

  cout << "Full course chicken count is " << m_num_chickens << "\n";
}

Edit: To be quite honest, I think the instructor made a mistake when they gave you the original code, since as other people have said, it's literally impossible to access m_fee from outside of Course, which is what you've been asked to do...

Gerblyn fucked around with this message at 16:40 on Aug 11, 2011

Oxyclean
Sep 23, 2007


Well "virtual void Report()=0;" in the parent class means it's pure virtual right?

But

quote:

void FullCourse::Report()
{
Course::Report();

cout << "Full course chicken count is " << m_num_chickens << "\n";
}

That worked. Thanks much again.

Oxyclean fucked around with this message at 16:48 on Aug 11, 2011

Dren
Jan 5, 2001

Pillbug

Gerblyn posted:

But if it has a body, then it's not pure, virtual :confused: Are you sure your instructor isn't just loving with you?

Oxyclean is for sure getting hosed with.

For a minute I was going to suggest that he hide the double in the last 4 bytes of the char array. I would never think to implement a pure virtual function without changing the function prototype. Doing so is both dirty and wrong.

Are you allowed to change the FullTimeCourse class definition? You could add the virtual keyword to the Report method and do:

code:
void Course::Report()
{
    std::cout << m_fee << std::endl;
}

void FullTimeCourse::Report()
{
    std::cout << m_id << std::endl;
}

int main()
{
    FullTimeCourse f(4.56, "pooptime");
    
    f.Report();

    Course *c = dynamic_cast<Course *>(&f);
    c->Report();
}

Dren fucked around with this message at 16:54 on Aug 11, 2011

Mr.Radar
Nov 5, 2005

You guys aren't going to believe this, but that guy is our games teacher.
In C++ you can define member functions that are declared as "pure virtual." You can even do it inline!
code:
#include <iostream>
using namespace std;

struct X {
	virtual void x() = 0 { cout << "here" << endl; }
};

struct Y : public X {
	void x() { cout << "y" << endl; X::x(); }
};

int main() {
	Y y;
	y.x();
}
Output:
code:
y
here
Declaring a member function as "pure virtual" just means it won't be referenced in the class's vtable (whether or not you define it) and that you won't be able to directly instantiate an instance of the class it's declared in (because it doesn't have a completely filled-in vtable).

more falafel please
Feb 26, 2005

forums poster

[quote="Mr.Radar"]
code:
struct X {
	virtual void x() = 0 { cout << "here" << endl; }
};
I had no idea you could do this, although it makes perfect sense.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Dren posted:

Are you allowed to change the FullTimeCourse class definition? You could add the virtual keyword to the Report method and do:

Methods with the same name and signature as a virtual method in a base class are implicitly virtual; they don't need to be redeclared as such, although it's good style to do so.

ETA:

Mr.Radar posted:

In C++ you can define member functions that are declared as "pure virtual." You can even do it inline!

That's an MSVC extension.

rjmccall fucked around with this message at 17:57 on Aug 11, 2011

Dren
Jan 5, 2001

Pillbug

rjmccall posted:

Methods with the same name and signature as a virtual method in a base class are implicitly virtual; they don't need to be redeclared as such, although it's good style to do so.

I take it destructors are a special case?

Gerblyn
Apr 4, 2007

"TO BATTLE!"
Fun Shoe
I don't think so. As far as I know, if the base class has a virtual destructor, all the child classes do as well.

Also, add me to the list of people who didn't know that MSVC let you define a body for a pure virtual method.

Edit: Virtual destructors are sort of a special case I guess, since you don't need to explicitly call the base destructor from the derived destructor; The system does it automatically.

Gerblyn fucked around with this message at 18:09 on Aug 11, 2011

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
It's a special case if you think of the name of the destructor as including the class name, yes. :)

Hughlander
May 11, 2005

Gerblyn posted:

In Visual Studio .NET, you go to the properties page of the project, then:

C/C++ -> Preprocessor -> Preprocessor Definitions

I think you're using VS2008? It's been years since I used that version, but I believe it's in the same place...

I know, but it's not listed there, and when I click on Command Line at the end of the C/C++ list, it's not listed there. However it is in the .vcproj file, and if I look at the obj file created, it shows up along with the rest of the command lines. I'm at an utter loss.

Gerblyn
Apr 4, 2007

"TO BATTLE!"
Fun Shoe
Is it possible that the project file is corrupted somehow? I don't know the scope of what you're working with, but maybe you could just create a new project and move all your code into it?

yippee cahier
Mar 28, 2005

Anyone have a good recommendation for learning how to debug C applications and libraries on Windows?

I can step through the execution of a program in VS no problem, but was never taught how to interpret a crash dump or how to properly build debug binaries to ensure crash dumps are useful. This knowledge would really come in useful right now.

Thanks in advance.

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!

Hughlander posted:

I know, but it's not listed there, and when I click on Command Line at the end of the C/C++ list, it's not listed there. However it is in the .vcproj file, and if I look at the obj file created, it shows up along with the rest of the command lines. I'm at an utter loss.
Someone asked earlier but not very clearly, are you in the right configuration? It's possible that the preprocessor definitions that you see in the file are for debug or release build only, and you're looking at the other one.

raminasi
Jan 25, 2005

a last drink with no ice
What on earth is the purpose of that MSVC extension :psyduck:? I cannot think of a single use case for that.

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!

GrumpyDoctor posted:

What on earth is the purpose of that MSVC extension :psyduck:? I cannot think of a single use case for that.
I guess it'd be nice for the case where you want a pure virtual class (eg. you don't ever want a "TreeNode", you only want a "TreeBranch" or "TreeLeaf") but you do want a partially shared behaviour, so you want to be able to start TreeBranch::Climb() by calling TreeNode::Climb() but you never want TreeNode::Climb() to be in a virtual function table because it isn't used on its own.

But it's pretty contrived and unnecessary, since you could get that behavior by just having a non-virtual TreeNode::BeginClimb() function or something in addition to the pure virtual one.

shrughes
Oct 11, 2008

(call/cc call/cc)
Yeah, you could just name it something else.

tractor fanatic
Sep 9, 2005

Pillbug
I assume it's because you need to be able to implement pure virtual destructors, so they just extended it to any kind of member function.

Adbot
ADBOT LOVES YOU

That Turkey Story
Mar 30, 2003

Gerblyn posted:


Also, add me to the list of people who didn't know that MSVC let you define a body for a pure virtual method.

All compliant compilers do. You can always define the body of a pure virtual function. The Microsoft extension he was talking about was that you can define them inside the class definition -- normally you have to define them outside of the definition.

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