I have a a.h which has a class d. I am wondering how to make a shorthand way to use the struct 'a' inside of my class.
//a.h
class d
{
public:
struct a
{
int val;
}
};
//a.cpp
#include "a.h"
using d::a; //line with error
a methodName()
{
//does stuff
return object_of_type_a;
}
what about this one
class d
{
public:
struct a
{
int val;
};
};
typedef struct d::a da;
Related
I'm trying to generate header files of classes I'm reconstructing from what I disassembled with IDA. However I'm getting compile errors due to circular dependencies. For regular classes I solved it by declaring them in a separate file I include as a first. The thing is I cannot declare inner class without definition of an outer class which is the problem.
An example class structure:
Class A:
#include "B.h"
class A {
public:
class Nested {
public:
void foo(B::Nested &foo);
};
};
Class B:
#include "A.h"
class B {
public:
class Nested {
public:
void foo(A::Nested &foo);
};
};
You can forward declare the Nesteds in A and B, and define them afterward.
a.h
class A {
public:
class Nested;
};
B.h
class B {
public:
class Nested;
};
Nested.h
#include "A.h"
#include "B.h"
class A::Nested {
public:
void foo(B::Nested &foo);
};
class B::Nested {
public:
void foo(A::Nested &foo);
};
Use templates.
class A {
public:
class Nested {
public:
template<class B>
void foo(typename B::Nested &fo);
};
};
class B {
public:
class Nested {
public:
template<class A>
void foo(typename A::Nested &fo);
};
};
template<>
void A::Nested::foo<B>(B::Nested &fo){
}
template<>
void B::Nested::foo<A>(A::Nested &fo){
}
e.g. (Here the template has been moved up so the type doesn't have to be specified with each function call.)
#include <iostream>
class A {
public:
template <class B>
class Nested {
public:
std::string name() const { return "a"; }
void foo(typename B:: template Nested<A> &fo);
};
};
class B {
public:
template <class A>
class Nested {
public:
std::string name() const { return "b"; }
void foo(typename A:: template Nested<B> &fo);
};
};
template<>
void A::Nested<B>::foo(B::Nested<A> &fo){
std::cout << "A::Nested " << fo.name() << '\n';
}
template<>
void B::Nested<A>::foo(A::Nested<B> &fo){
std::cout << "B::Nested " << fo.name() << '\n';
}
int main()
{
A::Nested<B> a;
B::Nested<A> b;
a.foo(b);
b.foo(a);
}
When a compiler reads your file it is expecting declared entities.
You can forward declare the class but you would be missing the Nested Parameter type.
What you can do is to have a third class which breaks the circular dependency and inherits to the your nested classes:
class NestedBase {
};
Now use this base in your A nested class:
#include "NestedBase.h"
class A {
public:
class Nested : public NestedBase {
public:
void foo(NestedBase &foo);
};
};
And in your B nested class as well:
#include "NestedBase.h"
class B {
public:
class Nested : public NestedBase {
public:
void foo(NestedBase &foo);
};
};
Now with dynamic_cast in your method implementations you can convert them to your desired types and access whatever you declared in your Nested Classes.
#include "A.h"
#include "B.h"
B::Nested::foo(NestedBase &foo)
{
auto &fooA = dynamic_cast<A::Nested&>(foo);
...
}
For my new project, I wanted to use my previous code as framework to speed up prototyping by avoiding rewriting code. In the code below, Derived struct belongs to the new project and it requires to define a new member, MoreElaborateMember which has stuff relevant to the new project. I want to use the function, foo from the base project to make changes on MoreElaborateMember but I can't. How can I solve this problem without touching to the base code?
#include <cassert>
struct SimpleMember
{
int a;
};
struct MoreElaborateMember: SimpleMember
{
// lots of other stuff
};
struct Base
{
SimpleMember member;
};
struct Derived: Base
{
MoreElaborateMember member;
};
void foo(Base& base)
{
base.member.a = -1;
}
int main()
{
Base base;
Derived derived;
foo(static_cast<Base&>(derived));
assert(derived.member.a == -1);
return 0;
}
Have you considered composing MoreElaborateMember from SimpleMember instead of inheriting? Might be a bit of boiler plate but I think it would achieve what you want if I've understood correctly.
struct SimpleMember
{
int a;
};
struct MoreElaborateMember
{
MoreElaborateMember(SimpleMember& s)
: a(s.a)
{}
int& a;
int b;
};
struct Base
{
SimpleMember member;
};
struct Derived : public Base
{
Derived()
: Base()
, member(Base::member)
{}
MoreElaborateMember member;
};
void foo(Base& base)
{
base.member.a = -1;
}
int main(int, char**)
{
Derived derived;
derived.member.a = 13;
derived.member.b = 42;
assert(derived.member.a == 13);
assert(derived.member.b == 42);
foo(derived);
assert(derived.member.a == -1);
assert(derived.member.b == 42);
return 0;
}
You will be more comfortable if you use polymorphism.
#include <cassert>
struct SimpleMember
{
int a;
};
struct MoreElaborateMember : SimpleMember
{
// lots of other stuff
};
struct Base
{
protected:
SimpleMember member;
public:
virtual void set_member(int m) = 0;
};
struct Derived : public Base
{
MoreElaborateMember member;
virtual void set_member(int m)
{
Base::member.a = m;
member.a = m;
}
};
void foo(Base* base)
{
base->set_member(-1);
}
int main()
{
Derived derived;
foo(&derived);
assert(derived.member.a == -1);
return 0;
}
I have a classes like so:
#include "B.h"
class A{
public:
std::vector<B> f[32];
}
#include "C.h"
class B{
public:
C thing;
}
class C{
public:
void func(arg1);
}
And I try to do this in main:
int main(){
B test;
for(int i = 0; i < 32; i++){
test.f[i]->thing.func(arg1);}
}
but it doesn't let me. I get an error on "test" object saying expression must have pointer type. What does this mean? How do I fix it?
Vector size is not set using subscript operator, you might want to use vector constructor to achieve what you are trying to do. Here is modified version of your code :
#include <iostream>
#include <vector>
using namespace std;
class C{
public:
void func(int arg1) {}
};
class B{
public:
C thing;
};
class A{
public:
std::vector<B> f;
A(): f(std::vector<B>(32)) {}
};
int main() {
A test;
for(int i = 0; i < 32; i++){
test.f[i].thing.func(i);}
return 0;
}
How do I initialize pointer class B foo inside class A? I am new to C++.
Header.h
namespace Core
{
enum type
{
Left, Right
};
template<type t>
class B
{
public:
B(int i);
private:
type dir;
int b = 12;
};
class A
{
public:
B<Left> *foo;
};
}
Source.cpp
namespace Core
{
template<type t>
B<t>::B(int i)
{
dir = t;
b = i;
}
}
int main()
{
Core::A *a = new Core::A;
a->foo = new Core::B<Core::Left>(10);
return 0;
}
Source.cpp needs a #include "Header.h" statement, and Header.h needs a header guard.
Also, you need to move the implemention of B's constructor into the header file. See Why can templates only be implemented in the header file?.
Try this:
Header.h:
#ifndef HeaderH
#define HeaderH
namespace Core
{
enum type
{
Left, Right
};
template<type t>
class B
{
public:
B(int i);
private:
type dir;
int b = 12;
};
class A
{
public:
B<Left> *foo;
};
template<type t>
B<t>::B(int i)
{
dir = t;
b = i;
}
}
#endif
Source.cpp
#include "Header.h"
int main()
{
Core::A *a = new Core::A;
a->foo = new Core::B<Core::Left>(10);
//...
delete a->foo;
delete a;
return 0;
}
I would suggest taking it a step further by inlining B's constructor and giving A a constructor to initialize foo:
Header.h:
#ifndef HeaderH
#define HeaderH
namespace Core
{
enum type
{
Left, Right
};
template<type t>
class B
{
public:
B(int i)
{
dir = t;
b = i;
}
private:
type dir;
int b = 12;
};
class A
{
public:
B<Left> *foo;
A(int i = 0)
: foo(new B<Left>(i))
{
}
~A()
{
delete foo;
}
};
}
#endif
Source.cpp
#include "Header.h"
int main()
{
Core::A *a = new Core::A(10);
//...
delete a;
return 0;
}
How do I initialize pointer class B foo inside class A?
Option 1
Construct a B<Left> with an assumed value.
class A
{
public:
B<Left> *foo = new B<Left>(0);
};
Option 2
Add a constructor of A that accepts an int that can be used to construct a B<Left> .
class A
{
public:
A(int i) : foo(new B<Left>(i)) {}
B<Left> *foo;
};
Word of caution
Before you down too far into using pointers to objects in your classes, consider the following:
What is The Rule of Three?
https://en.cppreference.com/w/cpp/memory, specially shared_ptr and unique_ptr.
Header.h
#pragma once
namespace
{
class B;
}
namespace n1
{
namespace n2
{
class A
{
private:
int i;
public:
friend class B;
};
}
}
Source.cpp
#include <stdio.h>
#include "Header.h"
class B
{
public:
void Run();
};
void B::Run()
{
n1::n2::A a;
a.i;
}
int main()
{
B b;
b.Run();
}
As we can see from above Class A is defined in header file while class B is defined in source file. I want to access private member of Class A from Class B::run(). I am not able to find the way to do this.
you are forward declaring class B in anonymous namespace
take out class B forward declaration out of the namespace and it should work
like this:
#pragma once
class B;
namespace n1
{
namespace n2
{
class A
{
private:
int i;
public:
friend class B;
};
}
}