496

Can a struct have a constructor in C++?

I have been trying to solve this problem but I am not getting the syntax.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294

17 Answers17

612

In C++ the only difference between a class and a struct is that members and base classes are private by default in classes, whereas they are public by default in structs.

So structs can have constructors, and the syntax is the same as for classes.

Piper
  • 1,266
  • 3
  • 15
  • 26
sth
  • 222,467
  • 53
  • 283
  • 367
  • 87
    And that structures will default to public when deriving from :) – GManNickG Jul 14 '09 at 19:15
  • 2
    @sth Your right on the difference between struct and class, however I think he's having a compile issue. The issue might be because of a union that is using the struct. You can't have non-trivial constructors in the type you have in a union. – Chap Jul 14 '09 at 20:18
  • 2
    @Chap: If he has concrete problems where the general solution doesn't work, it would probably be the best idea to post some code that shows the problem and the compiler errors that are generated. But as general as the question is asked I don't think one can really infer too much about the concrete problem the OP is trying to solve... – sth Jul 14 '09 at 20:36
  • 8
    @GMan: Right idea, wrong wording. A `struct` inherits its base classes publicly by default; there is no change to classes deriving from the `struct`. – Ben Voigt Apr 05 '13 at 17:37
  • 2
    @BenVoigt: Whoa. How'd you find this old comment. :) Yeesh wish I could edit it...even I'm confused at what I wrote. I think I omitted the word "bases" from the end but even that sucks. – GManNickG Apr 05 '13 at 23:40
  • Does Structure can also have destructors ? – Abhishek Gupta Jul 18 '13 at 14:15
  • @AbhishekGupta Yes it can have destructors as well. Like they are saying the only difference is related to inheritance. – Josh C Feb 22 '14 at 18:25
  • 1
    See my answer below, there is an additional difference that affects how you can do initialization of structure arrays -- a subtle point perhaps -- but used all over the place in WinSDK code... – Steve L Mar 07 '14 at 20:56
  • It seems that there should always be an implicit copy constructor with zero args for which one have to provide the default values for all arguments in the original constructor. Otherwise, I am getting an error like candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided. myConstructor(int a, int b) : a(a), b(b) {}; // incorrect one vs myConstructor(int a=0, int b=3) : a(a), b(b) {}; // correct one – Vlad Aug 02 '15 at 22:45
  • For some reason I thought that the constructor will be created automatically, like in Swift, lol – mrpaw69 Apr 17 '23 at 12:21
212
struct TestStruct {
        int id;
        TestStruct() : id(42)
        {
        }
};
nos
  • 223,662
  • 58
  • 417
  • 506
  • 70
    What is the `: id(42)` part called? – user13107 Feb 01 '13 at 05:59
  • 118
    @user13107: "[initializer list](http://en.cppreference.com/w/cpp/language/initializer_list)" is the word you're looking for. – Regexident Mar 06 '13 at 15:44
  • 7
    That won't work if you inherit from another class and the variable is decleared in the parent class. –  May 22 '13 at 20:41
  • 23
    @user152949: No one said it would. We could all comment on all code excerpts saying 'This won't work if [some totally different scenario]', but what's the point? – underscore_d Jul 25 '17 at 10:16
  • Hi, i'm a beginner with this, what is the need of '{ }' after id(42) ? (Why is it there) and is it always left empty? – varungupta Mar 11 '20 at 10:15
  • 1
    @varungupta It's the body of the constructor function. There's no code we want to run in the constructor in this case, so it's empty. – nos Mar 11 '20 at 13:31
  • The moment constructor is called id will be initialized with the value of 42. – sasha May 14 '21 at 13:46
66

All the above answers technically answer the asker's question, but just thought I'd point out a case where you might encounter problems.

If you declare your struct like this:

typedef struct{
int x;
foo(){};
} foo;

You will have problems trying to declare a constructor. This is of course because you haven't actually declared a struct named "foo", you've created an anonymous struct and assigned it the alias "foo". This also means you will not be able to use "foo" with a scoping operator in a cpp file:

foo.h:

typedef struct{
int x;
void myFunc(int y);
} foo;

foo.cpp:

//<-- This will not work because the struct "foo" was never declared.
void foo::myFunc(int y)
{
  //do something...
}

To fix this, you must either do this:

struct foo{
int x;
foo(){};
};

or this:

typedef struct foo{
int x;
foo(){};
} foo;

Where the latter creates a struct called "foo" and gives it the alias "foo" so you don't have to use the struct keyword when referencing it.

gitarooLegend
  • 11
  • 2
  • 2
  • what about when: typedef struct foo{ int x; foo(int x){}; }foo; foo::foo(int x){...}; this does not work... – Chris Jan 23 '17 at 01:23
  • alternatively you can define: `struct foo{ int x; foo(){}; };` and then: `typedef struct foo foo;` – Guy Sadoun Oct 18 '21 at 09:23
43

As the other answers mention, a struct is basically treated as a class in C++. This allows you to have a constructor which can be used to initialize the struct with default values. Below, the constructor takes sz and b as arguments, and initializes the other variables to some default values.

struct blocknode
{
    unsigned int bsize;
    bool free;
    unsigned char *bptr;
    blocknode *next;
    blocknode *prev;

    blocknode(unsigned int sz, unsigned char *b, bool f = true,
              blocknode *p = 0, blocknode *n = 0) :
              bsize(sz), free(f), bptr(b), prev(p), next(n) {}
};

Usage:

unsigned char *bptr = new unsigned char[1024];
blocknode *fblock = new blocknode(1024, btpr);
Vishnu CS
  • 748
  • 1
  • 10
  • 24
Luqmaan
  • 2,052
  • 27
  • 34
41

Class, Structure and Union is described in below table in short.

enter image description here

Saurabh Raoot
  • 1,303
  • 3
  • 26
  • 31
37

Yes, but if you have your structure in a union then you cannot. It is the same as a class.

struct Example
{
   unsigned int mTest;
   Example()
   {
   }
};

Unions will not allow constructors in the structs. You can make a constructor on the union though. This question relates to non-trivial constructors in unions.

Community
  • 1
  • 1
Chap
  • 2,776
  • 24
  • 31
18

In c++ struct and c++ class have only one difference by default struct members are public and class members are private.

/*Here, C++ program constructor in struct*/ 
#include <iostream>
using namespace std;

struct hello
    {
    public:     //by default also it is public
        hello();    
        ~hello();
    };

hello::hello()
    {
    cout<<"calling constructor...!"<<endl;
    }

hello::~hello()
    {
    cout<<"calling destructor...!"<<endl;
    }

int main()
{
hello obj;      //creating a hello obj, calling hello constructor and destructor 

return 0;
}
Kulamani
  • 509
  • 6
  • 13
17

Syntax is as same as of class in C++. If you aware of creating constructor in c++ then it is same in struct.

struct Date
{
    int day;

    Date(int d)
    {
        day = d;
    }

    void printDay()
    {
        cout << "day " << day << endl;
    }
};

Struct can have all things as class in c++. As earlier said difference is only that by default C++ member have private access but in struct it is public.But as per programming consideration Use the struct keyword for data-only structures. Use the class keyword for objects that have both data and functions.

sitaram chhimpa
  • 471
  • 7
  • 12
16

Yes. A structure is just like a class, but defaults to public:, in the class definition and when inheriting:

struct Foo
{
    int bar;

    Foo(void) :
    bar(0)
    {
    }
}

Considering your other question, I would suggest you read through some tutorials. They will answer your questions faster and more complete than we will.

GManNickG
  • 494,350
  • 52
  • 494
  • 543
16

Note that there is one interesting difference (at least with the MS C++ compiler):


If you have a plain vanilla struct like this

struct MyStruct {
   int id;
   double x;
   double y;
} MYSTRUCT;

then somewhere else you might initialize an array of such objects like this:

MYSTRUCT _pointList[] = { 
   { 1, 1.0, 1.0 }, 
   { 2, 1.0, 2.0 }, 
   { 3, 2.0, 1.0 }
};

however, as soon as you add a user-defined constructor to MyStruct such as the ones discussed above, you'd get an error like this:

    'MyStruct' : Types with user defined constructors are not aggregate
     <file and line> : error C2552: '_pointList' : non-aggregates cannot 
     be initialized with initializer list.

So that's at least one other difference between a struct and a class. This kind of initialization may not be good OO practice, but it appears all over the place in the legacy WinSDK c++ code that I support. Just so you know...

Steve L
  • 1,523
  • 3
  • 17
  • 24
  • This seems like incorrect behavior from the compiler (assuming the `class` version declares its members as `public`). MS says ["Visual C++ does not allow data types in an aggregate that contains constructors"](https://msdn.microsoft.com/en-us/library/0s6730bb.aspx), but doesn't indicate why that wouldn't apply to classes as well. And it seems to work in VS 2015. – mgiuffrida Jan 31 '17 at 09:46
  • works fine with the latest bits in VS 2017 Preview 4 as well. API version 141 – Aluan Haddad Jul 20 '17 at 19:05
  • So Aluan, are you saying that VS2017 now allows the initializer list for structs with constructors? I haven't tried the preview yet... Thanks! – Steve L Jul 21 '17 at 21:03
  • But what is `MyStruct` and `MYSTRUCT`? Why it has two names? – Kirby Jan 07 '23 at 15:58
  • Hm, got an error: `error: 'MYSTRUCT' does not name a type`. it does not work for C++ in Arduino... =( – Kirby Jan 07 '23 at 16:01
  • Kirby, see the item "Named Structs" in discussed here https://www.w3schools.com/cpp/cpp_structs.asp. MyStruct is the name of the struct (it's class name), and MYSTRUCT is supposed to be an instance of the struct (an object). With the Microsoft C++ compiler, however, I was using MYSTRUCT as an alias for MyStruct, which probably isn't the same as for your Arduino version of C++. Hope that helps. – Steve L Feb 06 '23 at 04:37
16

One more example but using this keyword when setting value in constructor:

#include <iostream>

using namespace std;

struct Node {
    int value;

    Node(int value) {
        this->value = value;
    }

    void print()
    {
        cout << this->value << endl;
    }
};

int main() {
    Node n = Node(10);
    n.print();

    return 0;
}

Compiled with GCC 8.1.0.

Luka Lopusina
  • 2,557
  • 3
  • 27
  • 32
15
struct HaveSome
{
   int fun;
   HaveSome()
   {
      fun = 69;
   }
};

I'd rather initialize inside the constructor so I don't need to keep the order.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
SwDevMan81
  • 48,814
  • 22
  • 151
  • 184
  • Members are always initialized in the order in which they appear in the class/struct body. Creating assignments in the constructor body is just that...assignments. – Raymond Valdes Apr 24 '14 at 01:47
13

Yes structures and classes in C++ are the same except that structures members are public by default whereas classes members are private by default. Anything you can do in a class you should be able to do in a structure.

struct Foo
{
  Foo()
  {
    // Initialize Foo
  }
};
heavyd
  • 17,303
  • 5
  • 56
  • 74
7

In C++ both struct & class are equal except struct'sdefault member access specifier is public & class has private.

The reason for having struct in C++ is C++ is a superset of C and must have backward compatible with legacy C types.

For example if the language user tries to include some C header file legacy-c.h in his C++ code & it contains struct Test {int x,y};. Members of struct Test should be accessible as like C.

Luqmaan
  • 2,052
  • 27
  • 34
Arunprasad Rajkumar
  • 1,374
  • 1
  • 15
  • 31
7

Yes it possible to have constructor in structure here is one example:

#include<iostream.h> 
struct a {
  int x;
  a(){x=100;}
};

int main() {
  struct a a1;
  getch();
}
Flexo
  • 87,323
  • 22
  • 191
  • 272
2

In C++, we can declare/define the structure just like class and have the constructors/destructors for the Structures and have variables/functions defined in it. The only difference is the default scope of the variables/functions defined. Other than the above difference, mostly you should be able to imitate the functionality of class using structs.

Roopesh Majeti
  • 556
  • 1
  • 11
  • 23
1

If you want, instead of using a constructor, you can use a struct initializer. There are a few ways to do that...

See: How to initialize a struct in accordance with C programming language standards

That is old school "C style", i.e. not new school "C++ style", but it works in C++ too of course.

BuvinJ
  • 10,221
  • 5
  • 83
  • 96