How do I declare a struct within a class? - c++

I want to declare a struct within a class which is private and I want to give a character value to a variable in the same struct, but I can't initialize it or cin it:
class puple
{
private:
struct p
{
char name[25];
int grade;
};
public:
puple(){};
void setme()
{
this->p::grade=99;
this->p::name[25]='g'; //here is the problem
}
void printme()
{
cout<<"Name: "<<this->p::name<<endl;
cout<<"Grade: "<<this->p::grade<<endl;
}
};
void main()
{
puple pu1;
pu1.setme();
pu1.printme();
}

You've describe a type called "p" which is a struct. There is yet no thing of type p around. Therefore your
p->...
calls make no sense.
Try declaring
p pInstance;
in your class and using it, ie:
void setme()
{
this->pInstance.grade=99;
this->pInstance.name[25]='g'; //here is the problem
}
Note even with this your assignment to name[25] will fail as the allowed indices for that array are 0 up to 24 (totalling 25 elements).

You have two serious problems here
struct p
{
char name[25];
int grade;
};
This defines a struct type, named p. I think what you wanted to do was
struct
{
char name[25];
int grade;
} p;
This will declare a struct, named p, with the name and grade member variables.
Your second serious problem is that you assign:
this->p::name[25]='g'; //here is the problem
This assigns 'g' to the 26th element of the array name. (arrays are 0-indexed)

isn't it
struct { ... } p; // variable of struct-type definition.
not
struct p { ... }; // type 'struct p' definition.
?

Place the struct definition outside of the class using a typedef. By having the struct defined in your .cpp file it will not be visible outside of your class.
#include <iostream>
typedef struct _foo
{
int a;
} foo;
class bar
{
public:
void setA(int newa);
int getA();
private:
foo myfoo;
};
void bar::setA(int newa)
{
myfoo.a = newa;
}
int bar::getA()
{
return myfoo.a;
}
using namespace std;
int main()
{
bar mybar;
mybar.setA(17);
cout << mybar.getA() << endl;
return 0;
}

Related

Member struct of a class prints incorrect attribute values in main, but has the right values in memory

Here's the code I was playing around with to understand member types inside a class better:
class First
{
struct trialStruct; //forward declaration
public:
First() : t {nullptr} //constructor
{
trialStruct temp {1,5};
cout<<temp.a<<" "<<temp.b<<endl<<endl; //attribute values of temporary struct variable
t = &temp;
cout<<t->a<<" "<<t->b<<endl<<endl; //attribute values of member struct variable
}
trialStruct* t; //member struct attribute
private:
struct trialStruct //struct
{
trialStruct(int aTemp , int bTemp) : a {aTemp} , b {bTemp}
{
//done
}
int a,b;
int sum();
};
};
int First::trialStruct::sum() //definition of struct function
{
return a+b;
}
int main()
{
//initialising object, printing struct attribute's attributes
First obj {};
cout<<obj.t->a<<endl;
cout<<obj.t->b<<endl;
cout<<obj.t->sum();
return 0;
}
The outputs in the contructor give the intended value of 1 and 5 for a and b. But the output in main gives output as follows: a = 1, b = 0, return value of sum(): 0
I don't know where I'm going wrong in my understanding of how this should work.
Output Screenshot:
EDIT:John Filleu's comment clarified what I was doing wrong. The temp object is destroyed after the constructor is exited, thus giving the trialStruct pointer undefined behavior.

Getting a value from a nested class in c++

Please I am trying to print out the value of a nested class from the private access specifier.
#include <iostream>
#include <cstdlib>
using namespace std;
class cal{
private:
int a = 0;
public:
int setNum(int m){
a = m;
}
void getNum(){
cout<<"the number is: "<<a<<endl;
}
class area{
public:
int setMan(int z){
cal obj;
obj.setNum(z);
return 1;
}
};
};
int main(){
cal::area obj2;
obj2.setMan(200);
cal obj3;
obj3.getNum();
'
return 0;
}
cal::area obj2;
obj2.setMan(200); is to set 200 to the nested class area and into the function setMan, of which setMan which pass the same value to the int setNum(int m){a = m;} this will set the value of a to "200". Then I wanted to print out the value of a but it displays 0 instead of 200.
Defining a nested class only provides a definition for a nested class. If you want to have a member of that class you have to declare it:
struct cal {
struct area {}; // class definition
area m_area; // member
};
int setMan(int z){
cal obj;
obj.setNum(z);
return 1;
}
The object obj is a temporary auto object and would be destroyed when you return from the function. By the way, "set" functions should not return values, returning 1 is confusing.
If you wish to connect objects somehow consider the composition or aggregation. For example:
// ...
class area{
public:
area(cal& obj) : obj(obj);
int setMan(int z){
obj.setNum(z);
return 1;
}
cal &obj;
};
// ...
int main(){
cal obj;
cal::area obj2(obj);
obj2.setMan(200);
obj.getNum();
return 0;
}
Anyway, that is just an artificial example, I don't see the reason you make area a nested class, the reason of setting values to cal from area, etc.

Class method points to other method of other class

i was wondering if is possible make that a method of class points to another method of other class:
consider this:
// Class Foo:
class Foo
{
static int GetA(int a);
static int GetB(int b);
};
int Foo::GetA(int a)
{
return a * 2;
}
int Foo::GetB(int b)
{
return a * 4;
}
// Hooking class methods:
class HookFoo
{
static int HookGetA(int);
static int HookGetB(int);
};
int(HookFoo::*HookGetA)(int) = (int(HookFoo::*)(int))0x0; // (0x0 Memory address) or for example: &Foo::GetA;
int(HookFoo::*HookGetB)(int) = (int(HookFoo::*)(int))0x0; // (0x0 Memory address) or for example: &Foo::GetA;
I know it's possible do some like:
int(*NewHook)(int) = &Foo::GetA;
but how i can do for declare the methods into of a class?
Here is more or less what you tried to achieve (minimal, working example):
class Foo
{
public:
static int GetA(int a);
static int GetB(int b);
};
int Foo::GetA(int a)
{
return a * 2;
}
int Foo::GetB(int b)
{
return b * 4;
}
class HookFoo
{
public:
using FuncType = int(*)(int);
static FuncType HookGetA;
static FuncType HookGetB;
};
// Initialized with Foo::GetA
HookFoo::FuncType HookFoo::HookGetA = &Foo::GetA;
// nullptr'ed
HookFoo::FuncType HookFoo::HookGetB = nullptr;
int main() {
HookFoo::HookGetA(0);
}
For the methods in Foo are static, you can use a simple function pointer type to refer to them. You don't have to use (and can't use actually) a member function pointer in this case.
The using declaration helps to have a more readable code.
When you have correctly initialized your hooks, you can invoke them (thus the pointed functions) as you can see in the main.
I added a couple of visibility specifiers for your methods and data members were all private.
You can use function pointers.
Ex:
class A {
public:
static void say_hello() { cout << "Hello\n"; }
};
class B {
public:
static void(*hook)();
};
void(*B::hook)() = A::say_hello;
int main()
{
B::hook();
}
If you need to hook into functions at a specific address, use a function pointer. You can't reassign functions like that
// typedef your function pointers, it makes the syntax a lot easier
typedef int(*FHook)(int);
class HookFoo
{
static FHook HookGetA;
static FHook HookGetB;
};
// assign to address
FHook HookFoo::HookGetA = (FHook)0x1234;
FHook HookFoo::HookGetB = (FHook)0x5678;
Of course its your job to make sure the addresses are correct.
the explicit function pointer types would be as such:
class HookFoo
{
static int (*HookGetA)(int);
static int (*HookGetB)(int);
};
int (*HookFoo::HookGetA)(int) = (int(*)(int))0x1234;
int (*HookFoo::HookGetB)(int) = (int(*)(int))0x5678;

C++ Class isn't returning the correct value of my private variable

Im trying to get this program to take the users input and put that into a public function and assign it to the privateVariable, then I want it to return the value of privateVariable to main() and output it to the screen, but all it displays is the value of an undefined int ( -858993460 ). What logical problem am I having here ?
#include <iostream>
#include <string>
using namespace std;
class MyClass
{
private:
int privateVariable;
public:
int userVariable;
void setVariable(int userVariable)
{
privateVariable = userVariable;
}
int getVariable()
{
return privateVariable;
}
};
int main()
{
int userVariable;
cin >> userVariable;
MyClass object1;
MyClass object2;
object1.setVariable(userVariable);
object2.getVariable();
cout << object2.getVariable();
system("PAUSE");
return 0;
}
You are setting in object1 and getting from object2. object1 and object2 are different objects. As variable in object2 is not set, you get a garbage value.
And I see no use of public userVariable in MyClass.
You are not setting the variable. You call setVariable on object1 and getVariable on object2, so the member of object1 remains uninitialized.
object1.setVariable(5); // object1.privateVariable = 5
// object2.privateVariable -> still uninitialized
object2.getVariable(); // returns uninitialized variable
For this to work, depending on what you want:
class MyClass
{
private:
static int privateVariable;
//......
}
This way, privateVariable will be a class-scoped member, not instance-scoped. That means it has the same value for all instances of the class (and even if instances were not created). This also means you can make both your functions static:
class MyClass
{
private:
static int privateVariable;
public:
static void setVariable(int userVariable)
{
privateVariable = userVariable;
}
static int getVariable()
{
return privateVariable;
}
};
and you can call the methods without instances:
MyClass::setVariable(5); //MyClass.privateVariable = 5;
MyClass::getVariable(); //returns 5
object1.getVariable(); //returns also 5
Another option is, if you don't want static members, to set the member for both objects:
object1.setVariable(5); // object1.privateVariable = 5
// object2.privateVariable -> still uninitialized
object2.setVariable(5); //object2.privateVariable = 5
object2.getVariable(); // returns 5
Or, you could define a constructor and set the variable there:
class MyClass
{
private:
static int privateVariable;
//......
public:
MyClass()
{
privateVariable = 5;
}
}
With this, every object you create will have the member initialized to 5.
object2 does not have your variable initialized as you set it on object1, the code you posted would only work if privateVariable was static.

C++ Dynamic Dispatch without Virtual Functions

I've got some legacy code that, instead of virtual functions, uses a kind field to do dynamic dispatch. It looks something like this:
// Base struct shared by all subtypes
// Plain-old data; can't use virtual functions
struct POD
{
int kind;
int GetFoo();
int GetBar();
int GetBaz();
int GetXyzzy();
};
enum Kind { Kind_Derived1, Kind_Derived2, Kind_Derived3 /* , ... */ };
struct Derived1: POD
{
Derived1(): kind(Kind_Derived1) {}
int GetFoo();
int GetBar();
int GetBaz();
int GetXyzzy();
// ... plus other type-specific data and function members ...
};
struct Derived2: POD
{
Derived2(): kind(Kind_Derived2) {}
int GetFoo();
int GetBar();
int GetBaz();
int GetXyzzy();
// ... plus other type-specific data and function members ...
};
struct Derived3: POD
{
Derived3(): kind(Kind_Derived3) {}
int GetFoo();
int GetBar();
int GetBaz();
int GetXyzzy();
// ... plus other type-specific data and function members ...
};
// ... and so on for other derived classes ...
and then the POD class's function members are implemented like this:
int POD::GetFoo()
{
// Call kind-specific function
switch (kind)
{
case Kind_Derived1:
{
Derived1 *pDerived1 = static_cast<Derived1*>(this);
return pDerived1->GetFoo();
}
case Kind_Derived2:
{
Derived2 *pDerived2 = static_cast<Derived2*>(this);
return pDerived2->GetFoo();
}
case Kind_Derived3:
{
Derived3 *pDerived3 = static_cast<Derived3*>(this);
return pDerived3->GetFoo();
}
// ... and so on for other derived classes ...
default:
throw UnknownKindException(kind, "GetFoo");
}
}
POD::GetBar(), POD::GetBaz(), POD::GetXyzzy(), and other members are implemented similarly.
This example is simplified. The actual code has about a dozen different subtypes of POD, and a couple dozen methods. New subtypes of POD and new methods are added pretty frequently, and so every time we do that, we have to update all these switch statements.
The typical way to handle this would be to declare the function members virtual in the POD class, but we can't do that because the objects reside in shared memory. There is a lot of code that depends on these structs being plain-old-data, so even if I could figure out some way to have virtual functions in shared-memory objects, I wouldn't want to do that.
So, I'm looking for suggestions as to the best way to clean this up so that all the knowledge of how to call the subtype methods is centralized in one place, rather than scattered among a couple dozen switch statements in a couple dozen functions.
What occurs to me is that I can create some sort of adapter class that wraps a POD and uses templates to minimize the redundancy. But before I start down that path, I'd like to know how others have dealt with this.
You can use a jump table. This is what most virtual dispatches look like under the hood, and you CAN construct it manually.
template<typename T> int get_derived_foo(POD*ptr) {
return static_cast<T>(ptr)->GetFoo();
}
int (*)(POD*) funcs[] = {
get_derived_foo<Derived1>,
get_derived_foo<Derived2>,
get_derived_foo<Derived3>
};
int POD::GetFoo() {
return funcs[kind](this);
}
For a short example.
What exactly are the limitations of being in shared memory? I realized that I don't know enough here. Does it mean that I can't use pointers, because someone in another process will be trying to use those pointers?
You could use a string map, where each process gets it's own copy of the map. You'd have to pass this in to GetFoo() so that it can find it.
struct POD {
int GetFoo(std::map<int, std::function<int()>& ref) {
return ref[kind]();
}
};
Edit: Of course, you don't have to use a string here, you could use an int. I just used it as example. I should change it back. Infact, this solution is pretty flexible, but the important thing is, make a copy of process-specific data, e.g. function pointers or whatever, and then pass it in.
Here's the template-metaprogramming path I'm going down now. Here is what I like about it:
Adding support for a new kind only requires updating LAST_KIND and adding a new KindTraits.
There is a simple pattern for adding a new function.
Functions can be specialized for particular kinds if necessary.
I can expect compile-time errors and warnings, rather than mysterious run-time misbehavior, if I screw anything up.
There are a couple of concerns:
POD's implementation is now dependent upon the interfaces of all the derived classes. (This is already true in the existing implementation, so I'm not worried about it, but it is a bit of a smell.)
I'm counting on the compiler to be smart enough to generate code that is roughly equivalent to the switch-based code.
Many C++ programmers will scratch their heads upon seeing this.
Here's the code:
// Declare first and last kinds
const int FIRST_KIND = Kind_Derived1;
const int LAST_KIND = Kind_Derived3;
// Provide a compile-time mapping from a kind code to a subtype
template <int KIND>
struct KindTraits
{
typedef void Subtype;
};
template <> KindTraits<Kind_Derived1> { typedef Derived1 Subtype; };
template <> KindTraits<Kind_Derived2> { typedef Derived2 Subtype; };
template <> KindTraits<Kind_Derived3> { typedef Derived3 Subtype; };
// If kind matches, then do the appropriate typecast and return result;
// otherwise, try the next kind.
template <int KIND>
int GetFooForKind(POD *pod)
{
if (pod->kind == KIND)
return static_cast<KindTraits<KIND>::Subtype>(pod)->GetFoo();
else
return GetFooForKind<KIND + 1>(); // try the next kind
}
// Specialization for LAST_KIND+1
template <> int GetFooForKind<LAST_KIND + 1>(POD *pod)
{
// kind didn't match anything in FIRST_KIND..LAST_KIND
throw UnknownKindException(kind, "GetFoo");
}
// Now POD's function members can be implemented like this:
int POD::GetFoo()
{
return GetFooForKind<FIRST_KIND>(this);
}
You can experiment with Curiously recurring template pattern. It's a bit complicated, but when you cannot use pure virtual functions it can be helpful.
Here is an approach that uses virtual methods to implement the jump table, without requiring the Pod class or the derived classes to actually have virtual functions.
The objective is to simplify adding and removing methods across many classes.
To add a method, it needs to be added to Pod using a clear and common pattern, a pure virtual function needs to be added to PodInterface, and a forwarding function must be added to PodFuncs using a clear and common pattern.
Derived classes need only have a file static initialisation object to set things up, otherwise look pretty much like they already do.
// Pod header
#include <boost/shared_ptr.hpp>
enum Kind { Kind_Derived1, Kind_Derived2, Kind_Derived3 /* , ... */ };
struct Pod
{
int kind;
int GetFoo();
int GetBar();
int GetBaz();
};
struct PodInterface
{
virtual ~PodInterface();
virtual int GetFoo(Pod* p) const = 0;
virtual int GetBar(Pod* p) const = 0;
virtual int GetBaz(Pod* p) const = 0;
static void
do_init(
boost::shared_ptr<PodInterface const> const& p,
int kind);
};
template<class T> struct PodFuncs : public PodInterface
{
struct Init
{
Init(int kind)
{
boost::shared_ptr<PodInterface> t(new PodFuncs);
PodInterface::do_init(t, kind);
}
};
~PodFuncs() { }
int GetFoo(Pod* p) const { return static_cast<T*>(p)->GetFoo(); }
int GetBar(Pod* p) const { return static_cast<T*>(p)->GetBar(); }
int GetBaz(Pod* p) const { return static_cast<T*>(p)->GetBaz(); }
};
//
// Pod Implementation
//
#include <map>
typedef std::map<int, boost::shared_ptr<PodInterface const> > FuncMap;
static FuncMap& get_funcmap()
{
// Replace with other approach for static initialisation order as appropriate.
static FuncMap s_funcmap;
return s_funcmap;
}
//
// struct Pod methods
//
int Pod::GetFoo()
{
return get_funcmap()[kind]->GetFoo(this);
}
//
// struct PodInterface methods, in same file as s_funcs
//
PodInterface::~PodInterface()
{
}
void
PodInterface::do_init(
boost::shared_ptr<PodInterface const> const& p,
int kind)
{
// Could do checking for duplicates here.
get_funcmap()[kind] = p;
}
//
// Derived1
//
struct Derived1 : Pod
{
Derived1() { kind = Kind_Derived1; }
int GetFoo();
int GetBar();
int GetBaz();
// Whatever else.
};
//
// Derived1 implementation
//
static const PodFuncs<Derived1>::Init s_interface_init(Kind_Derived1);
int Derived1::GetFoo() { /* Implement */ }
int Derived1::GetBar() { /* Implement */ }
int Derived1::GetBaz() { /* Implement */ }
Here is an example using Curiously recurring template pattern. This may suit your needs if you know more info at the compile time.
template<class DerivedType>
struct POD
{
int GetFoo()
{
return static_cast<DerivedType*>(this)->GetFoo();
}
int GetBar()
{
return static_cast<DerivedType*>(this).GetBar();
}
int GetBaz()
{
return static_cast<DerivedType*>(this).GetBaz();
}
int GetXyzzy()
{
return static_cast<DerivedType*>(this).GetXyzzy();
}
};
struct Derived1 : public POD<Derived1>
{
int GetFoo()
{
return 1;
}
//define all implementations
};
struct Derived2 : public POD<Derived2>
{
//define all implementations
};
int main()
{
Derived1 d1;
cout << d1.GetFoo() << endl;
POD<Derived1> *p = new Derived1;
cout << p->GetFoo() << endl;
return 0;
}
Expanding on the solution you ended up with, the following solves the mapping to derived functions at program initialization:
#include <typeinfo>
#include <iostream>
#include <functional>
#include <vector>
enum Kind
{
Kind_First,
Kind_Derived1 = Kind_First,
Kind_Derived2,
Kind_Total
};
struct POD
{
size_t kind;
int GetFoo();
int GetBar();
};
struct VTable
{
std::function<int(POD*)> GetFoo;
std::function<int(POD*)> GetBar;
};
template<int KIND>
struct KindTraits
{
typedef POD KindType;
};
template<int KIND>
void InitRegistry(std::vector<VTable> &t)
{
typedef typename KindTraits<KIND>::KindType KindType;
size_t i = KIND;
t[i].GetFoo = [](POD *p) -> int {
return static_cast<KindType*>(p)->GetFoo();
};
t[i].GetBar = [](POD *p) -> int {
return static_cast<KindType*>(p)->GetBar();
};
InitRegistry<KIND+1>(t);
}
template<>
void InitRegistry<Kind_Total>(std::vector<VTable> &t)
{
}
struct Registry
{
std::vector<VTable> table;
Registry()
{
table.resize(Kind_Total);
InitRegistry<Kind_First>(table);
}
};
Registry reg;
int POD::GetFoo() { return reg.table[kind].GetFoo(this); }
int POD::GetBar() { return reg.table[kind].GetBar(this); }
struct Derived1 : POD
{
Derived1() { kind = Kind_Derived1; }
int GetFoo() { return 0; }
int GetBar() { return 1; }
};
template<> struct KindTraits<Kind_Derived1> { typedef Derived1 KindType; };
struct Derived2 : POD
{
Derived2() { kind = Kind_Derived2; }
int GetFoo() { return 2; }
int GetBar() { return 3; }
};
template<> struct KindTraits<Kind_Derived2> { typedef Derived2 KindType; };
int main()
{
Derived1 d1;
Derived2 d2;
POD *p;
p = static_cast<POD*>(&d1);
std::cout << p->GetFoo() << '\n';
p = static_cast<POD*>(&d2);
std::cout << p->GetBar() << '\n';
}