Is the following valid C++ code?
If it is, what is it supposed to do?
typedef 开发者_高级运维struct Foo_struct{
Dog d;
Cat* c;
struct Foo_struct(Dog dog, Cat* cat){ this->d = dog; this->c = cat;}
} Foo;
(back story: porting a program written in Visual C++ (on Windows) to g++ (on MacOSX); no idea what this code is suppoesd to do).
Thanks!
I don't think it is. (And Comeau agrees with me.) You cannot define a constructor like this.
In C++, struct names are first-class citizens. There's no need to employ the old typedef
trick from C. Also, d
and c
should be initialized in a member initialization list. This would be valid (and better (C++):
struct Foo {
Dog d;
Cat* c;
Foo(Dog dog, Cat* cat) : d(dog), c(cat) {}
};
The code defines a struct (in C++, the same as a class, except that its members are public by default) with a constructor to initialize its members upon creation.
Edit: As Travis said in his comment, you might want to consider passing dog
as a const
reference instead of copying it:
Foo(const Dog& dog, Cat* cat) : d(dog), c(cat) {}
If Dog
(which we haven't seen) is a class with more than one built-in member, this might be considerably cheaper than passing it per copy.
No it's not. You cannot have the struct
in the constructor. A valid C++ code with minimal change would be
typedef struct Foo_struct{
Dog d;
Cat* c;
Foo_struct(Dog dog, Cat* cat){ this->d = dog; this->c = cat;} // <-- remove the "struct"
} Foo;
For a better approach see @sbi's answer.
Mostly, though the struct
and typedef
are unnecessary. Better written in C++ as:
class Foo {
public:
Foo(Dog dog, Cat *cat) : d(dog), c(cat) {}
private:
Dog d;
Cat *c;
};
Line-by-line:
class Foo {
The same as struct Foo
. The only difference in C++ between a class
and a struct
is that a struct
's members are public by default, while a class
's members are private. But we need some public members somewhere, so we get around that with...
public:
Everything after this is public, and can be accessed by anyone with a Foo
object.
Foo(Dog dog, Cat *cat) : d(dog), c(cat) {}
This is the constructor for Foo. It makes a new Foo
object, given a Dog
and a Cat *
. The : d(dog), c(cat)
is an initializer list. It is the same as this->d = dog; this->c = cat;
except probably faster. If you didn't want to do it that way, you could leave off the this->
unless there was a naming conflict somewhere. The {}
is the function body, empty because we moved the assignment to the initializer list.
private:
Opposite of public:
. Things declared after this can only be accessed inside our class, and are for internal use only.
Dog d;
Cat *c;
These are the class's internal variables, like the members of a struct
.
It's almost legal but has one error. A struct is just like a class except the default protection is public instead of private.
Okay, let's break it down:
// The next line is defining a struct called "Foo_struct", it's also
// saying it's going to give an alternate type name (that's the typedef).
// The alternate type name comes after the definition.
typedef struct Foo_struct{
// The structure has a Dog element (this means we need to have seen
// the definition of Dog already).
Dog d;
// And has a pointer to cat (this means we need to have at least seen
// a declaration of Cat)
Cat* c;
// Okay, this is definining a constructor. The constructor must be
// called with a Dog object and a pointer to a cat which the constructor
// will save in the object.
//
// Here is the one error. That 'struct' at the start shouldn't
// be there (commenting out to make the code legal).
/* struct */ Foo_struct(Dog dog, Cat* cat){ this->d = dog; this->c = cat;}
// And here we close out the struct and also finish off the typedef
// started on the first line.
} Foo;
It looks like it defines a structure called Foo_Struct, which holds an instance of Dog, have a pointer to a cat, and have a constructor which takes in an instance of Dog, pointer to Cat, and assign them to itself.
Then creates an instance of Foo on the stack.
Edit: I'm not sure whether that third line is a constructor or something else.
精彩评论