Structure initialization in class objects - c++

How do I initialize the structure variables of type class objects? I have the following code:
#include<iostream>
using namespace std;
class bitmap {
public :
bitmap() { clear() ;}
get();
set();
clear();
static const int a=10;
};
bitmap::get() {
};
struct bitmap_list {
bitmap_list_value _value;
}
int main()
{
bitmap bitmap_list_value;
bitmap_list bbbb;
bbbb. _value=bitmap_list_value.a;
cout << bbbb._value << endl;
}
Is this code correct, or is it possible to initialize the structure containing the class objects? This is the error I receive:
>error: ‘struct error: ‘_bitmap_list_value’ does not name a type
>error:bitmap_list’ has no member named ‘_value’

No, this code is not correct. You're referencing a type bitmap_list_value which is never declared.
Based on your comment ("bitmap_list_value is object of class bitmap"), it sounds as if you also have this, but haven't included it in your question's code for some reason:
typedef bitmap bitmap_list_value;
But yes, of course you can include members of class types inside structs. A struct is more or less a class with all fields made public by default, you can define methods inside structs just as you can with classes, and so on.

Related

How to access correct class member?

I've been running across this snippet of code and after execution I found out that everything compiles and executes fine (the int code member of the derived class is set to 65). However I was wondering how would one be able to access the char code member of the derived class?
#include <iostream>
using namespace std;
class base {
public:
base() : code('B') { }
char code;
};
class derived : public base
{
public:
int code;
};
int main(void)
{
derived d;
d.code = 65;
std::cout << d.code;
};
By specifying the correct scope for the base member variable using a qualified name lookup, as follows:
d.base::code = 'x'
std::cout << d.base::code << '\n';
See this section on qualified name lookups for more details.

Issue in using structure in different functions of different classes

In IHello.hpp file
#include "trees.hpp" // EDITED this line
namespace world
{
class IHello
{
public:
struct hi
{
char a;
};
void func(plants a); //// EDITED this line
};
}
In Hello.hpp file
#include "IHello.hpp"
class Hello : public world::IHello
{
private:
void new_world(hi *init); // function in which struct is used
hi init; // initialization of structure , in this file it does not give error
};
In trees.hpp // different file where I want to use the structure
#include "IHello.hpp"
enum plants
{
cactus = 0x01
}
class trees
{
public:
void new_func(hi *b); // using that structure here, shows error of hi structure has not been declared
// 2nd method - void new_func(world::IHello::hi *b) // error that world has not been declared and 2nd error - error: expected ',' or '...' before '*' token
};
So what do I need to do in order to get the structure which is initialized in class IHello to be visible in class which does not inherit IHello?
There is no error in class Hello because it inherits class world::IHello. The structure hi is part of that class, and because it's not a private declaration, it is visible to and usable by Hello too.
The error in class trees is because this class does not inherit world::IHello and there is no type named hi within the naming scope of where that member function is declared. That type only exists within the class world::IHello.
To fix the error, you must qualify the name so that the compiler knows what you want:
void new_func(world::IHello::hi *b);

Member Function as Friend: Is the book Lippman 5th wrong?

Lippman 5th
ISBN-13: 978-0321714114
Page 280-281, it says:
Making A Member Function a Friend
Rather than making the entire Window_mgr class a friend, Screen can
instead specify that only the clear member is allowed access. When we
declare a member function to be a friend, we must specify the class of
which that function is a member:
class Screen {
// Window_mgr::clear must have been declared before class Screen
friend void Window_mgr::clear(ScreenIndex);
// ... rest of the Screen class
};
Making a member function a friend requires careful structuring of our
programs to accommodate interdependencies among the declarations and
definitions. In this example, we must order our program as follows:
First, define the Window_mgr class, which declares, but cannot define, clear. Screen must be declared before clear can use the
members of Screen.
Next, define class Screen, including a friend declaration for clear.
Finally, define clear, which can now refer to the members in Screen.
The problem is: class Window_mgr has a data member that depends of class
Screen definition. See:
class Window_mgr {
public:
// location ID for each screen on the window
using ScreenIndex = std::vector<Screen>::size_type;
// reset the Screen at the given position to all blanks
void clear(ScreenIndex);
private:
std::vector<Screen> screens{Screen(24, 80, ' ')};
};
So it is impossible firstly define Window_mgr without defining Screen
previously!
And at the same time, it is impossible define Screen without we have
defined Window_mgr!!!
How can this problem be solved???
Is the book wrong?
I will paste here a code so that you can repeat the problem using a
minimal code:
#include <iostream>
#include <string>
#include <vector>
class A
{
friend void B::hello();
public:
A(int i) : number{i} {}
private:
void f() {
std::cout << "hello" << std::endl;
}
int number;
};
class B {
private:
std::vector<A> x{A(10)};
public:
void hello()
{
for(A &elem : x)
{
elem.f();
}
}
};
int main()
{
A x;
return 0;
}
If I compile this code, the result is:
error: use of undeclared identifier 'B'
friend void B::hello();
And if I invert the position (A <--> B), I have:
error: use of undeclared identifier 'A'
std::vector x{A(10)};
Is there a correct way to do that??
Thank you!
EDIT:
Thank you, Craig Young
Solution:
#include <iostream>
#include <string>
#include <vector>
class A;
class B {
private:
std::vector<A> x;
public:
B();
void hello();
};
class A
{
friend void B::hello();
public:
A(int i) : number{i} {}
private:
void f() {
std::cout << "hello" << std::endl;
}
int number;
};
B::B() : x{A(10)}
{
}
void B::hello()
{
for(A &elem : x)
{
elem.f();
}
}
int main()
{
return 0;
}
Conclusion:
the book is incomplete in that it doesn't expose the necessity of doing the forward declaration of class A firstly and the impossibility to do in-class initialization in this case.
I didn't notice that the problem was the A(10), not the vector! That is, we can use incomplete type A (only declaration, without definition) when we are using it as Template argument to vector (because it doesn't create A object itself) but we can not use incomplete type A when defining a object, for example: A(10);
For a start
Well, you're not following the guidance correctly.
First, define the Window_mgr class, which declares, but cannot define, clear. Screen must be declared before clear can use the members of Screen.
You must declare B before A.
Next, define class Screen, including a friend declaration for clear.
Now declare A with B::hello() as a friend.
Finally, define clear, which can now refer to the members in Screen.
B:hello() can use the private members of A.
This has been covered before here: C++ Forward declaration , friend function problem
You've added complications
Furthermore you want declarations of B to reference A. To achieve this you need to forward declare A so that B knows of its existence.
And it's important to be aware that you have only "partial" access to A. You cannot 'fully use' A in the declaration of B. So the following line in B is wrong.
//You're trying to create A when you only know it exists.
//You don't have a full definition of A yet.
std::vector<A> x{A(10)};
//Replace the above with...
std::vector<A> x;
Of course you'll have to find another way to initialise x.
Sample code
#include <iostream>
#include <vector>
class A;
class B
{
private:
std::vector<A> x;
public:
void hello();
};
class A
{
friend void B::hello();
public:
A(int i): number(i) {}
private:
void f() { std::cout << "hello" << std::endl; }
int number;
};
void B::hello()
{
for(A &elem : x)
{
elem.f();
}
}
int main()
{
A a{5};
return 0;
}
You have to have an earlier declaration, but not an earlier definition.
Adding
class A;
class B;
at the front tells the compiler that “A” and “B” refer to classes. That should be enough for it to reason out the rest.

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

Structures as attributes

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;