Classes

There's something I don't understand about classes. I mean, when I declare a class type which contains a member whose value rely on other members within the class, i.e.:
1
2
3
4
5
class foo
{ public:
    int a,b;
int x=a+b;
} obj;

, it pops up the following errors:
1.C:\Users\Andreutza\Desktop\xfjkfxfxkj\main.cpp|6|error: 'foo::a' cannot appear in a constant-expression|
C:\Users\Andreutza\Desktop\xfjkfxfxkj\main.cpp|6|error: 'foo::b' cannot appear in a constant-expression|
C:\Users\Andreutza\Desktop\xfjkfxfxkj\main.cpp|6|error: ISO C++ forbids initialization of member 'x'|
C:\Users\Andreutza\Desktop\xfjkfxfxkj\main.cpp|6|error: making 'x' static|
C:\Users\Andreutza\Desktop\xfjkfxfxkj\main.cpp|6|error: ISO C++ forbids in-class initialization of non-const static member 'x'|
C:\Users\Andreutza\Desktop\xfjkfxfxkj\main.cpp||In function 'int main()':|
C:\Users\Andreutza\Desktop\xfjkfxfxkj\main.cpp|12|error: 'class foo' has no member named 'sum'|
--------------------------------------------------
But when I put in something like this:
1
2
3
4
5
6
7
8
class foo
{ public:
    int a,b;
int sum(void)
{
    return a+b;
}
} obj;

, it gives me no error.
And I don't understand why. I mean, in the second example it's also a kind of assignment but between a function and a value returned by the sum of those variables, and as that function can take any value it means that it acts just like a variable , so I don't get the difference. It's like in the second example the function definition is jumped over until the compiler gets in the context of an object of that class, unlike the first example. So why is this happening? Thanks in advance!
Line 3: a and b are uninitialized. What do you think the value of x would be?

You can't initialize x like that unless a and b are const.
You can from C++11 hence.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <limits>


class foo
{ public:
    int a,b;
    int x=a+b;
} obj;


void waitForEnter();


int main()
{
    std::cout << "obj.x: " << obj.x << '\n';
    waitForEnter();
    return 0;
}


void waitForEnter()
{
    std::cout << "\nPress ENTER to continue...\n";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

(Note: compiles with zero errors, but a lot of warnings)
output:
obj.x: 0


What you really should do (IMHO) is getting rid of that... ehm... outdated?... C style:
1
2
3
class foo {
   ...
} obj;


1
2
3
4
5
6
7
8
9
10
11
12
class foo {
public:
    int a,b;
    int x=a+b;
};

    ...

int main()
{
    foo obj;
    std::cout << "obj.x: " << obj.x << '\n';

Last edited on
Take one more look. The question isn't about the way I could avoid the situation but WHY is it happening. I personally don't need that piece of code to work, I just need to understand the way the compiler interprets it ( or why was that standard applied ). For instance, one of the errors mentioned above said "making x static", which for me doesn't make sense. From what I know, a static variable is a variable that avoid being executed for more than 1 times, except the first time, and thus I don't see any bound.
Last edited on
a static variable is a variable that avoid being executed for more than 1 times, except the first time

I’m not sure: I’ve never succeeded in executing a variable.

Take one more look. The question isn't about the way I could avoid the situation but WHY is it happening.

You don’t need to avoid any situation any more: your code now works, apart from the fact that, as AbstractionAnon wisely pointed out, if you sum two uninitialised variables you can’t know what you get (the compiler also complains about that). You could potentially overflow, I’m afraid.

why was that standard applied

Ah, ok! I’m sorry, you are right. You were asking why... in the past...
Ok, I don’t know. Sorry again.

BTW, talking of classes, a variable declared static inside a class is a variable which is shared between all instances of that class.

Happy coding!
Here is all the code combined and a main that demonstrates some of the points.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using namespace std;

class foo {
public:
    int a,b;
    int x=a+b;

    int sum(void) {
	return a+b;
    }
} obj;

int main(int argc, char **argv)
{
    class foo bar;

    cout << "obj.x=" << obj.x << '\n';
    cout << "bar.x=" << bar.x << '\n';

    obj.a = 5;
    cout << "\nAfter obj.a=5, obj.x=" << obj.x << '\n';
    cout << "obj.sum() = " << obj.sum() << '\n';
}

obj.x=0
bar.x=-13120

After obj.a=5, obj.x=0
obj.sum() = 5


Line 7 tells the compiler how to initialize member variable x in the constructor. One big problem here is that it's initializing it with a and b, which are themselves uninitialized. When printing obj.x at line 18 this isn't a problem since globals are zero-initialized, but when printing
bar.x
at line 19, I get the strange value -13120. That's because bar is a local variable. It contains whatever happened to be in that memory before main() was called.

You asked about the difference between a sum() function and initializing variable x. In contrast the x, which is set in the constructor, the sum() function computes the sum when it's called. That means that if you change member a (line 21), the value of x will remain unchanged, but the value returned by sum() will take the new value of a into account. That why, at line 22, obj.x is still 0, but obj.sum() returns 5.

Hope this helps.
Topic archived. No new replies allowed.