-4
#include <iostream>
#include <string>
using namespace std;

class Box {
  // attributes
public:
  int size = 1;
  string type;
  Box(int size, string type) {}
};

int main() {
  Box e(2, "b");
  int b = e.size;
  cout << b;
}

I know I can get what I want by setting the parameters in the constructor as new_size and new_type then just setting size equal to new_size and etc but how come this doesn't work?

When I create the object e and use the constructor parameters am I not setting size equal to 2 and type equal to "b"?

t.niese
  • 39,256
  • 9
  • 74
  • 101
  • 7
    Yes, you are not setting the members. Your constructor does nothing. – MikeCAT Aug 12 '21 at 13:56
  • Not sure if this should be used as a dupe, but this will show you how to correctly write constructors: https://stackoverflow.com/questions/1711990/what-is-this-weird-colon-member-syntax-in-the-constructor – NathanOliver Aug 12 '21 at 13:58
  • 1
    You have given your class members and constructor parameters the same names, `size` and `type`. I think that's making you confuse the two and perhaps think they are the same. – Drew Dormann Aug 12 '21 at 13:58
  • 1
    Remove the constructor altogether and use `Box e{2, "b"};`? That's a useful technique for small "throwaway" classes. – Bathsheba Aug 12 '21 at 13:58
  • Why do you expect that `Box(int size, string type) {}` should set the member variables `size` and `type` to a value? Besides that the parameters of the constructor and the member variables share the same name in your code there is no other relation between them. – t.niese Aug 12 '21 at 14:06
  • Well like idk when creating the object I'm creating the object with Box e(2,"b") should that not basically mean that size = 2 and type = "b" –  Aug 12 '21 at 14:37
  • How are they not the same? They both have the same data type and the same name? Isn't it just that they're in different scopes? How are they not the same –  Aug 12 '21 at 14:58

2 Answers2

3

Write in your constructor body assignments of attributes something like this:

this->size = size;
this->type = type;

Or use initialization list:

Box(const int size, const string& type) : size(size), type(type) {}

Without it your object is not being initialized properly.

  • 1
    I would not bother recommending the "in-body" method. The body should only contain code that can't be managed in the initialization section. – sweenish Aug 12 '21 at 15:01
1

Your constructor should look more like this:

Box(int s, string t) : size(s), type(t)
{
}

Note that (1) the members are initialized before the body of the constructor (you could have used normal assignment within the constructor if you prefer) and (2) the parameters passed to the constructor have been renamed to avoid confusing them with the class members.

Tim Randall
  • 4,040
  • 1
  • 17
  • 39
  • 1
    FWIW, `Box(int size, string type) : size(size), type(type) {}` is also perfectly acceptable. – NathanOliver Aug 12 '21 at 14:05
  • 3
    @NathanOliver I take that as an example of the compiler being smarter than the programmer. I prefer to make this easy on the reader, rather than rely on them understanding exactly why there's no ambiguity. – Tim Randall Aug 12 '21 at 14:07
  • 1
    I'm with @NathanOliver on this, and would expect C++ programmers to learn the language properly. (That said, I use `m_` for my member variables, so I don't need to rely on IDEs that have nice syntax highlighting. Easier then to debug code under duress with only *vi* available.) – Bathsheba Aug 12 '21 at 14:51
  • OT: You should be passing the `string` by `const` reference. This prevents the compiler from copying the string from the caller. – Thomas Matthews Aug 12 '21 at 16:43