Sorry for naive question in C++. For below code, there is a class, inside which there is a union declaration having two variables. How to access the variables in the union using the class object in code below:
class my
{
public:
//class member functions, and oeprator overloaded functions
public:
union uif
{
unsigned int i;
float f;
};
private:
//some class specific variables.
};
if there is an object of type my defined like
my v1;
in a function later
Using v1 how do i access float f; inside union above in code?
also I want to watch the value of this float f in the watch window of a debugger(VS-2010), how to do that?
I tried v1.uif.f , this gave error in the watch window as : Error oeprator needs class struct or union.
v1.
You are only defining the union within the scope of the class, not actually creating a member variable of its type. So, change your code to:
class my
{
public:
//class member functions, and oeprator (sic) overloaded functions
public:
union uif
{
unsigned int i;
float f;
} value;
private:
//some class specific variables.
};
Now you can set the member variables in your union member, as follows:
my m;
m.value.i=57;
// ...
m.value.f=123.45f;
You never actually defined any member of that union. You only ever defined the union itself. There is no spoon float.
You've only defined the type of the uniion, you've not yet declared an object of this union type.
Try this:
class my
{
public:
union uif
{
unsigned int i;
float f;
};
uif obj; //declare an object of type uif
};
my v;
v.obj.f = 10.0; //access the union member
One option I don't see already here is that of an Anonymous Union, which is where you have no type or instantiation. Like so:
class my
{
public:
//class member functions, and oeprator (sic) overloaded functions
function(int new_i) { i = new_i;}
function(float new_f) { f = new_f;}
public:
union /* uif */
{
unsigned int i;
float f;
};
private:
//some class specific variables.
};
my m;
m.i=57;
m.f=123.45f;
Remember that with unions, it is only defined to read from the last member variable written to.
You have defined your union in your class, but you haven't created an instance of it! Try:
union uif
{
unsigned int i;
float f;
} myUif;
And then use v1.myUif.f (or i).
Related
In the bellow, the values of enum inside the class can be accessed by the name of the class.(I didn't even instantiate the class!)
class Shifting
{
public:
enum Value: char
{
UP, RIGHT, DOWN, LEFT
};
private:
Value value_;
};
std::cout << Shifting::RIGHT << std::endl; // 1
Does this mean that enum within a class is static?
If not, how to statically declare an enum?
This
enum Value: char
{
UP, RIGHT, DOWN, LEFT
};
this is a declaration of a type. It is not a data member of the enclosing class. The class has only this private data member.
Value value_;
of the enumeration data.
An enumerations declaration declares named enumerators. But they in turn are not data members of the enclosing class.
It is the same if you will declare a nested structure inside a class. For example
struct A
{
struct B
{
int x = 10;
};
B b;
};
Here is only one data member of the class A that is B b. The data member inside the structure declaration only provides the declaration of the structure B.
class myClass
{
private:
struct myStruct
{
int width = 0;
};
public:
myClass();
void changeValue();
};
myClass::myClass()
{
myStruct aStruct;
aStruct.width = 24;
}
void myClass::changeValue()
{
aStruct.width = 23;
}
I made the simple code above in order to test classes. In the member function changeValue i get the error saying that aStruct is not defined. But i don't really understand why it says it's undefined. Previously when i worked with classes this kind of code has worked fine. The difference between then and now is that in the class constructor i used pointers. So does this type of code only work for pointers and not for structs?
The reason i want this to work is it would be really usefull to have this "global" object that belongs to the class that is a struct.
This is not trouble with "understanding classes". You should go back and understand what "scope" is, which is one of basic concept of C++ language.
myStruct aStruct;
belongs to scope of member function myClass::myClass() and ceases to exist when execution of that function ends. This is completely different scope, aStruct variable doesn't exist there.
void myClass::changeValue()
{
aStruct.width = 23; // aStruct doesn't exist in any available scope
}
Now about declarations:
class myClass
{
private:
struct myStruct
{
int width = 0;
};
This code doesn't declare a struct storage inside of classmyClass. It declares member type myStruct (which is a class-type) inside of class myClass.
(Be wary of this name convention, it's very confusing. It's recommended to use capitalization like that only for members. Classes recommended to be all lower case or starting with capital letter.)
class myClass
{
private:
struct myStruct
{
int width = 0;
};
myStruct aStruct; // myClass got field aStruct
public:
myClass() : aStruct {24} {}
void changeValue();
};
aStruct here belongs to the private part of scope of class, which is available for all members of this class. myStruct is also declared as private so can't be used outside of class, be that in child class or just in outer scope.
myClass() : aStruct {24} {}
This is a non-trivial (user-defined) constructor with initializer list. aStruct is field of this class, so it can be initialized with a value like this. It is different from this form
myClass()
{
aStruct.width = 24;
}
In latter case, aStruct would be initialized first (with 0 in width field, as you had instructed) and its constructor will be called, then myClasss constructor would change value of its field to 24.
Before your question gets busted, you got to understand that everything in {} is scoped inside those braces, thus your problem here is that you have:
myStruct aStruct;
inside constructor. So aStruct is local variable to the constructor. In order to fix your code move it just below struct definition.
class myClass
{
private:
struct myStruct
{
int width = 0;
};
// MOVE IT HERE
myStruct aStruct;
public:
myClass();
void changeValue();
};
myClass::myClass()
{
aStruct.width = 24;
}
void myClass::changeValue()
{
aStruct.width = 23;
}
Now all member functions can access aStruct.
I am trying to figure out to store a typedef in my class, how would I do that? In the example posted I want to create a class which allows me to initiate a number of objects with different "Fct" parameters, like "one" or "slope", and or even change an object's "Fct f" with a set function:
typedef double Fct(double);
double one(double x) { return 1; }
double slope(double x) { return x / 2; }
struct myFct : Shape {
myFct(Fct f)
:f(f) {}; //"f" is not a nonstatic data member of base class of class "myFct"
private:
Fct f;
};
Your typedef stands for a function type. That very typedef can be used to declare member functions. So your class has a member function f declaration. It accepts a double and returns a double.
I suspect what you want is a function pointer as a member variable. Do it explicitly:
struct myFct : Shape {
myFct(Fct *f)
:f(f) {}; //"f" is not a nonstatic data member of base class of class "myFct"
private:
Fct *f;
};
You may consider yourself lucky, having stumbled on a somewhat obscure feature.
Whenever I define a variable and give it a value at the same time inside a class, I get an error. What is the reason for this?
As you can see, this doesn't work...
class myClass {
private:
int x = 4; // error
};
But when I keep the variable undefined it does:
class myClass {
private:
int x;
};
Since no one else is using member initialization, I'll introduce you:
class myClass {
private:
int x;
public:
myClass() : x (4){}
};
It's always better to use this over assigning in the body of the constructor, since by the time the body begins, all user-defined members will have already been initialized whether you said so or not. Better to do it once and actually initialize the non-user-defined members, and it is the only method that works for both non-static const members, and reference members.
For example, the following will not work because x isn't being initialized in the body, it's being assigned to:
class myClass {
private:
const int x;
public:
myClass() {x = 4;}
};
Using a member initializer, however, will, because you're initializing it off the bat:
class myClass {
private:
const int x;
public:
myClass() : x (4){}
};
Note also that your int x = 4; syntax is perfectly valid in C++11, where it subs in for any needed initialization, so you'll benefit if you start using it.
Initialize your variables in the constructor.
class myClass {
private:
int x;
public:
myClass()
{
x = 4; // hope that it will work
}
};
Updated Answer:
According to chris, it is better to use member initialization
class myClass {
private:
const int x;
public:
myClass() : x (4){}
};
Instance variable are supposed to be defined using setter methods, IE: setX(input) or inside a constructor.
Do this insted:
class myClass
{
private:
static const int x = 4;
};
If you don't x to be either static or constant, use only int x; instead and initialize x in the constructor of the class.
Your class is like a blue print. It does not have any storage associated with it. When you instantiate an object of your class, that is akin to the building based on that blue print. Your object has storage and that can hold the value you give to the member variables.
Also, as others have pointed out, it is possible to do what you want in C++11. Check out:
http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2756.htm
In C++03,
only static const integral data members can be initialized within a
class.
Either initialize in the constructor, or make the data member static const:
class myClass {
private:
int x;
public:
myClass() {
x = 4;
}
};
or
class myClass {
private:
static const int x = 4;
};
For a code like this:
class foo {
protected:
int a;
public:
class bar {
public:
int getA() {return a;} // ERROR
};
foo()
: a (p->param)
};
I get this error:
invalid use of non-static data member 'foo::a'
currently the variable a is initialized in the constructor of foo.
if I make it static, then it says:
error: 'int foo::a' is a static data member; it can only be initialized at its definition
However I want to pass a value to a in the constructor.
What is the solution then?
In C++, unlike (say) Java, an instance of a nested class doesn't intrinsically belong to any instance of the enclosing class. So bar::getA doesn't have any specific instance of foo whose a it can be returning. I'm guessing that what you want is something like:
class bar {
private:
foo * const owner;
public:
bar(foo & owner) : owner(&owner) { }
int getA() {return owner->a;}
};
But even for this you may have to make some changes, because in versions of C++ before C++11, unlike (again, say) Java, a nested class has no special access to its enclosing class, so it can't see the protected member a. This will depend on your compiler version. (Hat-tip to Ken Wayne VanderLinde for pointing out that C++11 has changed this.)
In C++, nested classes are not connected to any instance of the outer class. If you want bar to access non-static members of foo, then bar needs to have access to an instance of foo. Maybe something like:
class bar {
public:
int getA(foo & f ) {return foo.a;}
};
Or maybe
class bar {
private:
foo & f;
public:
bar(foo & g)
: f(g)
{
}
int getA() { return f.a; }
};
In any case, you need to explicitly make sure you have access to an instance of foo.
The nested class doesn't know about the outer class, and protected doesn't help. You'll have to pass some actual reference to objects of the nested class type. You could store a foo*, but perhaps a reference to the integer is enough:
class Outer
{
int n;
public:
class Inner
{
int & a;
public:
Inner(int & b) : a(b) { }
int & get() { return a; }
};
// ... for example:
Inner inn;
Outer() : inn(n) { }
};
Now you can instantiate inner classes like Inner i(n); and call i.get().
You try to access private member of one class from another. The fact that bar-class is declared within foo-class means that bar in visible only inside foo class, but that is still other class.
And what is p->param?
Actually, it isn't clear what do you want to do
Your Question is not clear but there is use case when you will get this issue .
Invalid use of non-static data member.
When you are using "non-static data member in another class try to not use with scope resolution operator
Example::className::memberData = assignivalue ;
instead of above try to use object of className class;
Example:: m_pClassName->memberData=assignValue;*