So I have a header file:
struct inner1 {
int w;
int x;
};
struct inner2 {
int y;
int z;
};
struct outer{
inner1 *a;
inner2 *b;
};
Now in main, I want to initialize these structures and use them. How do I initialize all three structures so that outer recognizes inner1 and inner2 as the specific structs it points to. Then lets say I want to access the variable w. Is it outer.a->w? I am unfamiliar with nested structures dealing with pointers. Any help is appreciated.
struct inner1 {
int w;
int x;
};
struct inner2 {
int y;
int z;
};
struct outer{
inner1 *a;
inner2 *b;
};
int _tmain(int argc, _TCHAR* argv[])
{
outer o;
o.a = new inner1();
o.b = new inner2();
o.a->w = 1;
o.a->x = 2;
o.b->y = 3;
o.b->z = 4;
//do stuff
delete o.a;
delete o.b;
return 0;
}
This will permit you to declare and initialize the structures.
Here is a demonstrative program
#include <iostream>
int main()
{
struct inner1 {
int w;
int x;
};
struct inner2 {
int y;
int z;
};
struct outer{
inner1 *a;
inner2 *b;
};
outer o = { new inner1 { 10, 20 }, new inner2 { 30, 40 } };
std::cout << "o.a->w = " << o.a->w << ", o.a->x = " << o.a->x
<< ", o.b->y = " << o.b->y << ", o.b->z = " << o.b->z
<< std::endl;
delete o.a;
delete o.b;
}
The program output is
o.a->w = 10, o.a->x = 20, o.b->y = 30, o.b->z = 40
Or you could do the following way
#include <iostream>
int main()
{
struct inner1 {
int w;
int x;
};
struct inner2 {
int y;
int z;
};
struct outer{
inner1 *a;
inner2 *b;
};
inner1 i1 = { 10, 20 };
inner2 i2 = { 30, 40 };
outer o = { &i1, &i2 };
std::cout << "o.a->w = " << o.a->w << ", o.a->x = " << o.a->x
<< ", o.b->y = " << o.b->y << ", o.b->z = " << o.b->z
<< std::endl;
}
The approach depends on the task and using of the objects.
You are correct in both your assumptions.
As long as these three structures are defined in this order no further declarations have to be made.
Welcome to c++.
The biggest favour you will do yourself is to learn about the smart pointers early on.
It's almost always a mistake to write structures in terms of raw pointers.
#include <memory>
#include <iostream>
struct inner1 {
inner1(int a, int b) : w(a), x(b) {}
int w;
int x;
};
struct inner2 {
inner2(int a, int b) : y(a), z(b) {}
int y;
int z;
};
struct outer{
outer(int w, int x, int y, int z)
: a(std::make_unique<inner1>(w,x))
, b(std::make_unique<inner2>(y,z))
{}
std::unique_ptr<inner1> a;
std::unique_ptr<inner2> b;
};
int main()
{
auto p_outer = std::make_unique<outer>(1, 2, 3, 4);
return 0;
// p_outer.a and .b are destroyed automatically here
// and all memory is reclaimed.
}
Related
Haha, so I'm a little late to starting my homework and would enjoy having someone explain this to me, I read parts of my textbook so I understand the simple examples of base classes and derived classes but other than that I'm stumped. It doesn't seem to hard but I just need some help on where to start/look.
What is the output of the following C++ program?
#include <iostream>
#include <string>
using namespace std;
class baseClass {
public:
void print() const;
baseClass(string s = " ", int a = 0);
// Postcondition: str = s; x = a;
protected:
int x;
private:
string str;
};
class derivedClass : public baseClass {
public:
void print() const;
derivedClass(string s = "", int a = 0, int b = 0);
};
// Postcondition: str = s; x = a; y = b;private:int y;};
int main() {
baseClass baseObject("This is the base class", 2);
derivedClass derivedObject("DDDDDD", 3, 7);
baseObject.print();
derivedObject.print();
system("pause");
return 0;
}
void baseClass::print() const { cout << x << " " << str << endl; }
baseClass::baseClass(string s, int a) {
str = s;
x = a;
}
void derivedClass::print() const {
cout << "Derived class: " << y << endl;
baseClass::print();
}
derivedClass::derivedClass(string s, int a, int b)
: baseClass("Hello Base", a + b) {
y = b;
}
I haven't tried anything yet lol, just started my homework too late and it is due today and would love a quick explanation and help with the answer.
I have a bunch of derived structs. Is there any way for me to access the derived width without casting?
If I do this, I get 1s and not 42 and 13:
#include <iostream>
#include <deque>
using namespace std;
struct BaseParams {
virtual ~BaseParams() {}
int width = 1;
};
struct VectorParams : BaseParams {
int width = 42;
};
struct MatrixParams : BaseParams {
int width = 13;
};
int main()
{
std::deque<BaseParams *> params;
VectorParams *vectorParams = new VectorParams;
MatrixParams *matrixParams = new MatrixParams;
params.push_back(vectorParams);
params.push_back(matrixParams);
for (auto ¶m : params) {
std::cout << param->width << std::endl;
}
// Don't want to do this
// for (auto ¶m : params) {
// MatrixParams *matrixParams = dynamic_cast<MatrixParams *>(param);
// if (matrixParams)
// std::cout << matrixParams->width << std::endl;
// VectorParams *vectorParams = dynamic_cast<VectorParams *>(param);
// if (vectorParams)
// std::cout << vectorParams->width << std::endl;
// }
return 0;
}
If possible, I want to avoid casting because I have so many derived structs.
To overwrite the width in BaseParams, instead of making a new variable, you can give VectorParams a constructor like this:
struct VectorParams : BaseParams {
VectorParams() {
width = 42;
}
};
In fact constructors are always how variables are set in new objects. When you write
struct BaseParams {
virtual ~BaseParams() {}
int width = 1;
};
the compiler actually turns it into a constructor, similar to
struct BaseParams {
virtual ~BaseParams() {}
int width;
BaseParams() {
width = 1;
}
};
#include <iostream>
class A
{
public:
int func();
protected:
namespace B { enum { D = 0, E = 1 }; }
namespace C { enum { D = 0, E = 1 }; }
}
int A::func()
{
int x = A::B::D;
int y = A::C::E;
return x + y;
}
int main() {
A a;
int x = a.func();
std::cout << x << std::endl; // 1
return 0;
}
What's wrong with this code?
I am just curious and experimenting with namespace, because I'd like to have enums with same names of values.
I don't want to use enum class, because I cannot do operations with integer without overloading operators or casting.
You can't declare a namespace inside a class. Instead, what you can use is a struct like
#include <iostream>
class A
{
public:
int func();
protected:
struct B { enum { D = 0, E = 1 }; };
struct C { enum { D = 0, E = 1 }; };
};
int A::func()
{
int x = A::B::D;
int y = A::C::E;
return x + y;
}
int main() {
A a;
int x = a.func();
std::cout << x << std::endl; // 1
return 0;
}
which you can see working in this live example.
From the C++ 14 Standard (7.3.1 Namespace definition)
2 Every namespace-definition shall appear in the global scope or in a
namespace scope
So these namespace definitions within the class scope (where you forgot to place a semicolon)
class A
{
public:
int func();
protected:
namespace B { enum { D = 0, E = 1 }; }
namespace C { enum { D = 0, E = 1 }; }
};
^^^
are invalid.
How can I pass a structure name, object name, different member name(whose value to be verified) as a parameter to a function ?
struct st{
int a;
int b;
}
bool verify(____ st , ____ b){
if(obj.b == 5)return true;
return false;
}
int main(){
st obj;
// now that I know all the names of members of struct name
// HOW can I verify passing different member name as parameter
cout<<verify(__,__);
}
For an instance:
(example with error)
#include<iostream>
using namespace std;
struct st{
int a;
int b;
};
bool verify(st obj, st.a val){
if(obj.a==val)
return true;
}
int main()
{
cout<<"Hello World"<<endl;
st obj;
cout<<verify(obj,a);
//cout<<verify(obj,b);
return 0;
}
You can use a pointer to data member:
bool verify(const st &obj, int st::* field) {
return obj.*field == 5;
}
...
st obj;
std::cout << verify(obj, &st::a);
std::cout << verify(obj, &st::b);
But the syntax is confusing and just passing a reference to the data member to verify is easier:
bool verify(int field) {
return field == 5;
}
...
st obj;
std::cout << verify(obj.a);
std::cout << verify(obj.b);
Using a template:
#include <iostream>
struct st
{
int a;
int b;
};
struct st2
{
int c;
int d;
};
template<typename T>
bool verify(const T &obj, int T::* field)
{
return obj.*field == 5;
}
int main()
{
st obj = {5, 6};
st2 obj2 = {5, 6};
std::cout << verify(obj, &st::a) << "\n"; // 1, since obj.a is 5
std::cout << verify(obj2, &st2::d) << "\n"; // 0, since obj.d is not 5
return 0;
}
Here I have a very simple program. My aim is to let b equal c, that is to copy all the content of c into b. But I don't know how. The getdata() function returns a pointer pointing to array of objects c, but how can it be used to put c into b?
#include<iostream>
#include<stdlib.h>
using namespace std;
class A
{
public:
A(int i,int j):length(i),high(j){}
int length,high;
};
class B
{
private:
A c[3] = {A(9,9),A(9,9),A(9,9)};
public:
A* getdata()
{
return c;
}
};
int main()
{
A b[3]={A(0,0),A(0,0),A(0,0)};
B *x = new B();
cout<< x->getdata() <<endl;
cout << b[1].length<<endl;
return 0;
}
In modern C++, make yourself a favor and use a convenient container class to store your arrays, like STL std::vector (instead of using raw C-like arrays).
Among other features, std::vector defines an overload of operator=(), which makes it possible to copy a source vector to a destination vector using a simple b=c; syntax.
#include <vector> // for STL vector
....
std::vector<A> v; // define a vector of A's
// use vector::push_back() method or .emplace_back()
// or brace init syntax to add content in vector...
std::vector<A> w = v; // duplicate v's content in w
That's a possible partial modification of your code, using std::vector (live here on codepad):
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
A(int l, int h) : length(l), high(h) {}
int length, high;
};
class B
{
private:
vector<A> c;
public:
const vector<A>& getData() const
{
return c;
}
void setData(const vector<A>& sourceData)
{
c = sourceData;
}
};
int main()
{
vector<A> data;
for (int i = 0; i < 3; ++i) // fill with some test data...
data.push_back(A(i,i));
B b;
b.setData(data);
const vector<A>& x = b.getData();
for (size_t i = 0; i < x.size(); ++i) // feel free to use range-for with C++11 compilers
cout << "A(" << x[i].length << ", " << x[i].high << ")\n";
}
Instead of creating an array of A i.e. 'b' in main, create a pointer to A. And then initialize it by calling the getdata().
A *b;
B *x = new B();
b = x->getdata();
Here is an example
#include <iostream>
#include <algorithm>
class A
{
public:
A( int i, int j ) : length( i ), high( j ){}
int length, high;
};
class B
{
private:
A c[3] = {A(9,9),A(9,9),A(9,9)};
public:
A* getdata()
{
return c;
}
};
int main()
{
A b[3] = { A(0,0), A(0,0), A(0,0) };
B *x = new B();
A *c = x->getdata();
std::copy( c, c + 3, b );
for ( const A &a : b ) std::cout << a.length << '\t' << a.high << std::endl;
delete []x;
return 0;
}
The output is
9 9
9 9
9 9
Instead of standard algorithm std::copy you may use an ordinary loop. For example
for ( size_t i = 0; i < 3; i++ ) b[i] = c[i];