`public` access qualifier and `const`ness. `-Wuninitialized` - c++

class Foo
{
public:
const int x;
};
class Bar
{
private:
const int x;
};
Output:
test.cpp:10:13: warning: non-static const member ‘const int Bar::x’ in class without a constructor [-Wuninitialized]
Why does Barproduce a warning but Foo doesn't (obviously because of access qualifier, but what is the logic?).

With those definitions, since Foo::x is public, you can validly instantiate a Foo with something like:
Foo f { 0 }; // C++11
or
Foo f = { 0 };
You can't do that for a Bar.

Related

How to access members of forward declared class [duplicate]

This question already has answers here:
error: member access into incomplete type : forward declaration of
(2 answers)
Closed 4 years ago.
I'm trying to figure out how to access member variable of forward declared class though pointer.
My code:
#include <iostream>
class Boo;
class Foo{
public:
int getNum() {
return booPtr->num; //Error: Member access into incomplete type 'Boo'
}
Boo *booPtr;
};
class Boo : public Foo {
public:
Boo() {
booPtr = this;
}
int num = 45;
};
int main() {
Boo boo;
int num = boo.getNum();
std::cout << num << '\n';
}
The error I get :
"return booPtr->num" : Member access into incomplete type 'Boo'
The result I expect :
45
How can I fix this error and what would be more common and safer way to achieve the same thing?
When you access members of a class, the class has to be complete type; only forward declaration is not enough.
You can move the definition of the member function out of the class definition and after the definition of Boo.
class Boo;
class Foo{
public:
int getNum();
Boo *booPtr;
};
class Boo : public Foo {
...
};
int Foo::getNum() {
return booPtr->num;
}
You need to define the member function getNum() where the type Boo is known to the compiler. Hence change the class definition of Foo to
class Boo;
class Foo{
public:
int getNum();
Boo *booPtr;
};
Then comes the definition of Boo, and finally
int Foo::getNum()
{
return booPtr->num;
}

Passing to a function argument a reference member variable

Is it possible to pass to a function that has a reference argument a variable member of a class?
Let's say
class Foo
{
int A;
int B;
}
void foo(int& a)
{
a++;
}
void main()
{
Foo f;
foo(f.A);
}
Is this possible?
Yes, this is possible, and it works exactly how you expected it to.
But note that in your existing code, A and B are private (by default). That means nothing outside the class can access them, for any reason (which includes using them as references).
Declare them as them public:
class Foo
{
public:
int A;
int B;
};
or change Foo to a struct:
struct Foo
{
int A;
int B;
};

C++: Order of declaration in public and private

I am unsure about the order of declaration in my class. My compiler says error: "Foo" was not declared in this scope. If I change the order of public and private parts of the class, I end up with the same error. Also, if I want to use the getFoo(), and I am including my header file, the struct Foo type is not visible because it's private. But if I put it in public scope again, then public would have to come before private because otherwise the declaration of myFoo of type Foo can't happen since Foo was not decalred yet.
I am confused here... thanks for your help!
/*MyClass.h*/
class MyClass
{
private:
struct Foo{
int bar;
};
Foo myFoo;
public:
Foo getFoo(){ return myFoo;}
};
It has nothing to do with public or private. Your inner type has to be defined before it is used:
struct Foo
{
Bar bar() { return Bar(); } // ERROR
struct Bar {};
};
struct Foo
{
struct Bar {};
Bar bar() { return Bar(); } // OK
};
Note: there has been some confusion concerning the accessibility of a private type. THe type is accessible outside of its class, it just cannot be named. So, this code that accesses the private type is completely legal:
class Foo
{
struct Bar {
void do_stuff() const {}
};
public:
Bar bar() { return Bar(); } // OK
};
int main()
{
Foo f;
f.bar().do_stuff(); // use temporary Bar object
// In C++11, you can even make a named instance
auto b = f.bar(); // instantiate a Bar object called b
b.do_stuff(); // use it
}
Your struct Foo should be public otherwise getFoo getter will not work as Foo is accessible only inside your class

C++ Object Initialization outside main

I have some C++ code that produces an error:
class foo{
public:
int a;
int b;
};
foo test;
test.a=1; //error here
test.b=2;
int main()
{
//some code operating on object test
}
I get this error:
error: expected constructor, destructor, or type conversion before '.' token
What does the error mean and how do I fix it?
It's called a constructor. Include one that takes the wanted values as arguments.
Like
class foo
{
public:
foo(int aa, int bb)
: a(aa), b(bb) // Initializer list, set the member variables
{}
private:
int a, b;
};
foo test(1, 2);
As noted by chris, you can also use aggregate initialization if the fields are public, like in your example:
foo test = { 1, 2 };
This also works in C++11 compatible compilers with the constructor as in my example.
This should be:
class foo
{
public:
int a;
int b;
};
foo test;
int main()
{
test.a=1;
test.b=2;
}
You can not write code outside of a method/function, you can only declare variables/classes/types, etc.
You need a default constructor:
//add this
foo(): a(0), b(0) { };
//maybe a deconstructor, depending on your compiler
~foo() { };
You cannot call the variable initialization outside a function. As mentioned in a comment
test.a=1
test.b=2
is thus invalid. If you really need an initialization, use a constructor like
class foo
{
public:
foo(const int a, const int b);
int a;
int b;
}
Otherwise you could put the initialization e.g. into the main function.

Overriding Private Members of Parent Class

Given the following classes:
class foo
{
private:
int c;
public:
foo( int a = 42 ) { c = a; }
~foo();
};
class bar: public foo
{
public:
bar();
~bar();
};
How can I make bar override c with a different number? Can I do something like this?
bar::bar()
{
c = 12;
}
I get this error when trying to compile:
test.cpp: In constructor ‘bar::bar()’:
test.cpp:8:7: error: ‘int foo::c’ is private
Call your base class' constructor in the constructor initialization list:
bar::bar()
: foo(12)
{ }
Incidentally, you should always prefer using a constructor initialization list over assignment inside the constructor body, so your foo constructor would be better written as:
foo( int a = 42 ) : c(a) { }
Call the base class constructor:
bar::bar() : foo(12) { }
Edit: whoops
You should use getter and setter methods for your private variables.
So your calls foo should look like this:
class foo
{
private:
int c;
public:
foo( int a = 42 ) { c = a; }
virtual ~foo();
void setC (int tempC){
c=tempC;
}
int getC() const{
return c;
}
};
In the constructor of B you can call them the setter method:
bar::bar()
{
setC(12);
}
You should then always use your setter and getter methods to access your variable, instead of accessing it direct.
You should also declare your destructor of your base class virtual.
What about
bar::bar() : foo(12) {}