Structures as attributes - c++

These are the attributes of my class:
class Addition_Struct: public Addition {
// attributes
struct a {
int element;
struct a *next;
};
struct b {
int element;
struct b *next;
};
struct outcome {
int element;
struct outcome *next;
};
struct a a_data;
struct b b_data;
struct outcome outcome_data;
// methods
a convertToStackA(int); // everything is right with this line
How can I call them from inside the .cpp file? Using this->a syntax returns "type name is not allowed". Using a* as method's return value displays "Identifier is not allowed", and "Declaration is incompatible with...".
.cpp file:
a* Addition_Struct::convertToStackA(int number)
{
// identifier "a" is undefined, and declaration is incompatible
}

This:
class Addition_Struct: public Addition {
// attributes
typedef struct a {
int element;
struct a *next;
} a;
};
Only defines a type named Addition_Struct::a. There is no member a for you to access with this-a. Remove the typedef to get the member you want.
EDIT
The method definition you provided is not inline (it's outside the class definition). Therefore, you must use a fully scoped type name for the return type.
Addition_Struct::a* Addition_Struct::convertToStackA(int number)
{
}
since the compiler sees the type Addition_Struct::a but not the type a.

From within the class you can just use a. From outside the class use the fully qualified name Addition_Struct::a.
Btw since this is C++ you can just use
struct a {
int element;
a *next;
};
without the typedef.

In you example you only declared structures, so your Addition_Struct have 3 structures defined, but no data members. You need to add something like
a a_data;
b b_data;
outcome outcome_data;
after structure declarations, to be able access data members like:
this->a_data;
this->b_data;
this->outcome_data;

Related

pointer variable defined by typedef

I know that the code below works.
int* pn;
pn = new int;
So I tried to apply it in same way, in my custom class.
class Matrix {
private:
typedef struct ex_node* ex_pointer;
typedef struct ex_node {
int ex_data;
ex_pointer next;
};
public:
void examplefunction() {
ex_pointer node;
node = new ex_node; //error here
}
};
The error says that I cannot assign "ex_node*" type value to "ex_pointer"type entity.
But ex_pointer is defined as ex_node*.
Is ex_pointer different type from ex_node*?
How can I remove this error?
I like the question and Jason Liam already provided different ways to fix your code. But I'd like to answer your first questions, which are entirely valid: "The error says that I cannot assign "ex_node" type value to "ex_pointer"type entity. But ex_pointer is defined as ex_node*. Is ex_pointer different type from ex_node*?"
Let's check exactly what the compiler says:
error: incompatible pointer types assigning to 'Matrix::ex_pointer' (aka 'ex_node *')
from 'Matrix::ex_node *'
node = new ex_node;
^~~~~~~~~~~
So, the problem is that node is of type Matrix::ex_pointer, that is a ex_node *. new ex_node instead is of type Matrix::ex_node *. The former is a pointer to a struct ex_node defined in the global namespace, while the latter is a pointer to a struct ex_node defined within class Matrix.
Apparently forward declaring a struct within a typedef assumes that the struct is in the global namespace, which in your case is not correct. You can fix it (as suggested also by Jason Liam) by forward declaring your struct before the typedef:
class Matrix {
struct ex_node;
typedef struct ex_node* ex_pointer;
struct ex_node {
int ex_data;
ex_pointer next;
};
public:
void examplefunction() {
ex_pointer node;
node = new ex_node;
}
};
Finally: don't hide that pointer behind a typedef.
A more C++ way(and correct way) of doing this would be remove the unnecessary typedefs as shown below:
class Matrix {
private:
struct ex_node {
int ex_data;
//------vvvvvvvv---------->directly using ex_node* is more clear IMO
ex_node* next;
};
using ex_pointer = ex_node*;
public:
void examplefunction(){
//------vvvvvvvvvv---------->you can use ex_pointer if you really want
ex_pointer node;
node = new ex_node;; //works now
}
};
Demo
Method 2
If you want you can still use alias as shown below. Here we provide a forward declaration for ex_node inside the Matrix so that we can use typedef/using with it.
class Matrix {
private:
struct ex_node; //forward declaration
using ex_pointer = ex_node*;
struct ex_node {
int ex_data;
//------vvvvvvvvv---------->use ex_pointer
ex_pointer next;
};
public:
void examplefunction(){
ex_pointer node;
node = new ex_node;;
}
};

Class typedef defined outside of class

I am writing a class C which has an inner class T, and I'd like the details of T hidden as an internal implementation of C. Methods in C are all using pointers to T. This is of course possible as:
// In header
class C {
public:
class T;
T* f();
void g(T*);
};
// In .cpp
class C::T { /* details here */ };
Now my question is, how can I define C::T as a type alias of another one, in .cpp file. The following doesn't compile at all, but it illustrates what I want to do:
// Outside the class C
using C::T = std::string;
Is there any workaround to this, while maintaining the goal, i.e. hide the detail of C::T?
As others pointed out, it cannot be done. This is my suggestion:
// .h
class C {
public:
struct T;
T* f();
void g(T*);
};
// .cpp
struct C::T
{
IMPL_TYPE data;
//If one is carefull with lifetimes this can almost in any context act as IMPL_TYPE.
//And if necessary, the data member can be accessed.
operator IMPL_TYPE&(){return data};
}
You cannot, because the forward declaration class T; within class C declares a class type whose True Name is C::T, and is therefore not identical to the type whose True Name is std::basic_string<...>.
You might consider the following:
// C.h
#include "internal/T.h"
namespace foo {
class C {
public:
using T = internal::T;
// ...
};
}
// internal/T.h
namespace foo { namespace internal {
using T = std::string;
}}
The closest you can come to this would be to have your t derive from string:
class C::T : public std::string { ... };
T can never be truly hidden or redefined to be a type alias in a different .cpp file.
The following round about method should work for your needs.
class C
{
public:
// Use a base class for just the pointers.
struct TBase
{
virtual ~TBase() {}
};
TBase* f();
void g(TBase*);
// Allow client code to define a concrete type using a template parameter.
template <typename Data> struct T : TBase
{
Data data;
};
};
Then, in a .cpp file, use:
using Type = C::T<std::string>;
Type* obj = new Type;
obj->data = "Some string";
C c;
c.g(obj);
TBase* ptr = c.f();

C++ struct in header file

I'm not very familiar with structs.
But I created this:
in test.h:
class test {
public:
struct Astruct
{
int age;
int weight;
};
struct Astruct& MethodOne();
};
and in test.cpp:
#include "test.h"
test::test() {}
struct Astruct& test::MethodOne() {
Astruct testStruct;
// code to fill in testStruct
return testStruct;
}
The goal of this code above is that I'm able to return a struct with MethodOne.
But on the line of
struct Astruct & test::MethodOne(){
it says :error: declaration is incompatible with what's in the header file.
I don't understand this. If I'd replace the struct with an int return type there wouldn't be an error?
What's wrong here?
And a second error I'm getting when I return testStruct: Error: a reference of type "Astruct&" (not const qualified) cannot be initialized with a value of type "test::Astruct"
Your code has several errors (missing ; etc.). A class is not different from a struct in C++. The only difference is the default access specifier which is private in a class and public in a struct (members and inheritance).
Structs are typically used to indicate that it actually is just a data structure with no logic or methods. Imho they are nice to encapsulate input and output of methods. If you want to have it for a member function it could look like this:
class Foo{
public:
struct BarIn {}; // need ; here
struct BarOut {}; // and here
BarOut bar(const BarIn& b){return BarOut();}
};
int main() {
Foo::BarOut result = Foo().bar(Foo::BarIn());
}
Note that I had to write Foo:BarOut and Foo::BarIn, because the structs are declared inside the class. Also there is no need to write struct when you declare a variable of a type that is declared as struct (because there really is no difference between an instance of a class or struct).
Last but not least you should never return a reference (or pointer) to a local variable:
struct Astruct & test::MethodOne(){
Astruct testStruct;
return testStruct; // testStruct is destroyed here
} // and the returned ref is invalid

How to use structs declared private?

I'm working on a project with a pre-made .hpp file with all the declarations and stuff.
A struct is declared in the private part of the class, along with some private members.
I need to create an array with the type of the struct in my .cpp file.
//.hpp
private:
struct foo
{
std::string a;
unsigned int b;
};
std::string* x;
unsigned int y;
//.cpp
unsigned int returny()
{
return y; // No errors
}
foo newArray[10]; // Compile time error; unknown type name
Why is it that I can return y, which is also private, but not make an array out of the struct foo?
How can I fix this? (I'm in an introductory C++ class... so hopefully there's a simple solution)
There are couple of issues.
You can't use a type that's defined in the private section of class like you are trying.
The nested type can be used by specifying the appropriate scope.
EnclosingClass::foo newArray[10];
But this will work only if foo is defined in the public section of EnclosingClass.
you should define the struct int the outside of the class like this
struct Foo
{
std::string a;
unsigned int b;
};
class A {
private:
Foo foo;
...
}

Struct Constructor in C++?

Can a struct have a constructor in C++?
I have been trying to solve this problem but I am not getting the syntax.
In C++ the only difference between a class and a struct is that members and base classes are private by default in classes, whereas they are public by default in structs.
So structs can have constructors, and the syntax is the same as for classes.
struct TestStruct {
int id;
TestStruct() : id(42)
{
}
};
All the above answers technically answer the asker's question, but just thought I'd point out a case where you might encounter problems.
If you declare your struct like this:
typedef struct{
int x;
foo(){};
} foo;
You will have problems trying to declare a constructor. This is of course because you haven't actually declared a struct named "foo", you've created an anonymous struct and assigned it the alias "foo". This also means you will not be able to use "foo" with a scoping operator in a cpp file:
foo.h:
typedef struct{
int x;
void myFunc(int y);
} foo;
foo.cpp:
//<-- This will not work because the struct "foo" was never declared.
void foo::myFunc(int y)
{
//do something...
}
To fix this, you must either do this:
struct foo{
int x;
foo(){};
};
or this:
typedef struct foo{
int x;
foo(){};
} foo;
Where the latter creates a struct called "foo" and gives it the alias "foo" so you don't have to use the struct keyword when referencing it.
As the other answers mention, a struct is basically treated as a class in C++. This allows you to have a constructor which can be used to initialize the struct with default values. Below, the constructor takes sz and b as arguments, and initializes the other variables to some default values.
struct blocknode
{
unsigned int bsize;
bool free;
unsigned char *bptr;
blocknode *next;
blocknode *prev;
blocknode(unsigned int sz, unsigned char *b, bool f = true,
blocknode *p = 0, blocknode *n = 0) :
bsize(sz), free(f), bptr(b), prev(p), next(n) {}
};
Usage:
unsigned char *bptr = new unsigned char[1024];
blocknode *fblock = new blocknode(1024, btpr);
Class, Structure and Union is described in below table in short.
Yes, but if you have your structure in a union then you cannot. It is the same as a class.
struct Example
{
unsigned int mTest;
Example()
{
}
};
Unions will not allow constructors in the structs. You can make a constructor on the union though. This question relates to non-trivial constructors in unions.
In c++ struct and c++ class have only one difference by default struct members are public and class members are private.
/*Here, C++ program constructor in struct*/
#include <iostream>
using namespace std;
struct hello
{
public: //by default also it is public
hello();
~hello();
};
hello::hello()
{
cout<<"calling constructor...!"<<endl;
}
hello::~hello()
{
cout<<"calling destructor...!"<<endl;
}
int main()
{
hello obj; //creating a hello obj, calling hello constructor and destructor
return 0;
}
Yes. A structure is just like a class, but defaults to public:, in the class definition and when inheriting:
struct Foo
{
int bar;
Foo(void) :
bar(0)
{
}
}
Considering your other question, I would suggest you read through some tutorials. They will answer your questions faster and more complete than we will.
Note that there is one interesting difference (at least with the MS C++ compiler):
If you have a plain vanilla struct like this
struct MyStruct {
int id;
double x;
double y;
} MYSTRUCT;
then somewhere else you might initialize an array of such objects like this:
MYSTRUCT _pointList[] = {
{ 1, 1.0, 1.0 },
{ 2, 1.0, 2.0 },
{ 3, 2.0, 1.0 }
};
however, as soon as you add a user-defined constructor to MyStruct such as the ones discussed above, you'd get an error like this:
'MyStruct' : Types with user defined constructors are not aggregate
<file and line> : error C2552: '_pointList' : non-aggregates cannot
be initialized with initializer list.
So that's at least one other difference between a struct and a class. This kind of initialization may not be good OO practice, but it appears all over the place in the legacy WinSDK c++ code that I support. Just so you know...
One more example but using this keyword when setting value in constructor:
#include <iostream>
using namespace std;
struct Node {
int value;
Node(int value) {
this->value = value;
}
void print()
{
cout << this->value << endl;
}
};
int main() {
Node n = Node(10);
n.print();
return 0;
}
Compiled with GCC 8.1.0.
struct HaveSome
{
int fun;
HaveSome()
{
fun = 69;
}
};
I'd rather initialize inside the constructor so I don't need to keep the order.
Syntax is as same as of class in C++. If you aware of creating constructor in c++ then it is same in struct.
struct Date
{
int day;
Date(int d)
{
day = d;
}
void printDay()
{
cout << "day " << day << endl;
}
};
Struct can have all things as class in c++. As earlier said difference is only that by default C++ member have private access but in struct it is public.But as per programming consideration Use the struct keyword for data-only structures. Use the class keyword for objects that have both data and functions.
Yes structures and classes in C++ are the same except that structures members are public by default whereas classes members are private by default. Anything you can do in a class you should be able to do in a structure.
struct Foo
{
Foo()
{
// Initialize Foo
}
};
Yes it possible to have constructor in structure here is one example:
#include<iostream.h>
struct a {
int x;
a(){x=100;}
};
int main() {
struct a a1;
getch();
}
In C++ both struct & class are equal except struct'sdefault member access specifier is public & class has private.
The reason for having struct in C++ is C++ is a superset of C and must have backward compatible with legacy C types.
For example if the language user tries to include some C header file legacy-c.h in his C++ code & it contains struct Test {int x,y};. Members of struct Test should be accessible as like C.
In C++, we can declare/define the structure just like class and have the constructors/destructors for the Structures and have variables/functions defined in it.
The only difference is the default scope of the variables/functions defined.
Other than the above difference, mostly you should be able to imitate the functionality of class using structs.