C++ algorithm structure and classes [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I need to develop a fast algorithm, and the natural structure of the problem would be
class A {B b; C c;};
class B {};
class C {};
with some methods of class B and C using fields of class A. But I suppose that for scope reasons this is not possible.
How can I structure this better? Maybe including a class A pointer inside B and C?

Not including a pointer to A inside B and C, but including the pointer in the argument list of the methods that need the elements of A (not so good solution, though).
But if instances of B and C are part of the state of an instance of A and also need other parts of the instance of A, then you should think about moving the methods from B and C to A. Reason: if the method operates on b, c and other parts of a, then it is likely, that it is an behaviour of a.

A naive (straightforward) solution is to simply pass a reference to A to constructors for both B and C:
class B
{
public:
B (const A& a) : mA (a) {}
private:
const A& mA;
};
Or maybe better yet, pass references to the fields you actually need:
class B
{
public:
B (const int& foo, const std::string& bar) : mFoo (foo), mBar (bar) {};
private:
const int& mFoo;
const std::string mBar;
};
But the fact that the problem at hand leads me to this kludgy straightforward solution is a code smell. I suspect that the entire design is broken.
I wonder what A's real purpose really is? Is it simply to be a holder for a B and a C? Does it have a job? Is it trying to do too much?
Or maybe the problem is in the opposite direction. Maybe in an attempt to squeeze every single thing in to an object-shaped box, you have created a machine that is more complicated than it needs to be. Should B's and C's tasks really be the responsibility of A? Or perhaps even (gasp) free functions?

You may need to use interfaces, i.e abstract base classes for B and C, let's call them IB and IC (interface to B and C).
a.h includes ib.h and ic.h.
The services provided by B and C are only used through the interface base classes.
b.h and c.h includes a.h. (and of course ib.h and ic.h, respectively).
But if only the implementation of B and C needs A, then you can manage without the interface base classes - just include a.h only in b.cpp and c.cpp, thereby avoiding the circular dependence in header files.

Related

Initialization without recursion [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I'm trying to do a bit of refactoring and I am curious about how would you approach this problem.
Basically I'm trying to create an initialization function for each class. There are classes that inherit from some others, and i would like to use parent initialization function if possible. How would you address this?
I would like to use these structs with memcpy and maybe using also them with the keywords align and __attribute__((packed)); and they must be usable with extern "C". I would exclude then constructors and destructors.
An example to explain:
struct A
{
int a;
};
void initialize(A& a)
{
a = 0;
}
struct B : A
{
int b;
};
void initialize(B& b)
{
initialize(b); // here I want void initialize(A& a), not recursion
b = 0;
};
Maybe I have to do some kind of cast? Ideally I'm looking a solution that does not create overhead.
Use a static_cast.
In your code, the initialize(b) call will recurse infinitely, because b is better matched as B& than as A& (the argument of the function you want to call), thus the overload resolution picks the same function and recurs.
You specified that you want to initialise the A part of the b object. Why not tell that to the compiler? Tell it that you want to call initialise in it as though it was an A, like so:
initialize(static_cast<A&>(b));
As for your concern that you mentioned in the comment - no copies are being made here. If I used static_cast<A>, however, a temporary object would be created, but that's not the case. I am not casting b to an object of a type A. I am casting it to a reference of a type A, which will result in creation of temporary reference. Since A& matches with A& better than with B&, the first function will be chosen, thus avoiding the recursion.

Class Inheritance default constructor cannot be referenced [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
Questions : 33978185 , 32569833 didn't helped me.
By the way, in question 33978185 this error is considered as a bug, but since im using VS2017 i think it should be fixed by now.
Question 40181845 is using structs and i dont understand it quite well...
Question 38469597 says that i should make class B - friend class, is that the case here too?
I tried to search for more solutions but i havent got what i need.
Consinder my level of programming knowledge of object oriented c++ : Advanced> Normal > Begginer.
I am Normal.
I have class A, and class B:
class A
{
protected:
int q;
int w;
public:
A(int);
functionE();
functionR();
};
class B:public A
{
public:
functionT();
};
in main when i want to create a object of class B, I get error:
the default constructor "objectname" cannot be referenced -- its a deleted function.
From my knowledge of object oriented programming, when some members are protected, they can be accessed by the inherited class, and if inheritance is public, it can access public function.
I want my class B to have bonus functionT() and nothing else, but as i said, be able to access protected members of class.
One solution is to actually code functionT() in class A, which removes the need for class B, but I don't want that.
What should i do?
When you're trying to create an object of class B, you get an error as you didn't declare any constructor. B can't have a default constructor, as A doesn't have one either (when you declared A(int) as A constructor, you implicitly deleted the default constructor).
You can either create a default constructor for A, or default it by A() = default
or create a constructor for B, like so
B() : A(0) {}
B(int i) : A(i) {}
By providing the constructor A(int) the default constructor A() gets deleted. However, when creating an instance of class B it must call the constructor of its superclass A. The only way you provide is calling the default constructor, which doesn't exist anymore and thus your code does not compile.
In order for it to compile, you need to tell B how it is supposed to construct A. You can for example add this constructor to B: B(int a) : A(a) {}
Since you have a custom constructor for class A it needs to be called by the constructor of class B.
The generated 'empty' constructor of class B tries to call the 'empty' one of class A, which is no longer available. So you need to write a constructor for B as well.
class B : public A
{
public:
B() : A(0) {}
/* or */
B(int v) : A(v) {}
};

Can I change the type of an object at runtime in C++ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I have 2 objects in my C++ program, both extending from the same parent class:
class A, and class B, both extending class base.
Is it possible create an object using class A, and then change it later in the program to class B?
Short answer, no. You cannot safely cast from A to B or B to A. You can safely cast to the base class since A IS_A base class and B IS_A base class but A and not a B and vice versa. There is no portable or safe way to do this. Whilst your compiler might let you do it and whilst it might appear to work the result of casting between to unrelated classes in this manner is undefined.
Incidentally, there is no reason why you can't add a cast constructor to allow A to be constructed from B and vice versa. That would be perfectly safe. You would just use the members of A to initialise the members of B and vice versa. Any members that are not common you'd have to deal with, probably be assigning them default values.
The following code works:
#include <iostream>
class Base {};
struct A : public Base {int a;};
struct B : public Base {int b;};
int main()
{
A *a = new A();
a->a = 1;
B *b = reinterpret_cast<B *>(a);
std::cout << b->b << std::endl;
return 0;
}
This is extremely ugly though and won't work properly if A and B don't have the exact same memory layout. This works if you need a and b to be the same object. If you don't mind them being different objects and residing in different places in memory then you can just write a constructor in B that receives an object of type A or a conversion operator.
This sounds like a classic example of the XY Problem and there probably exists a much more elegant solution to your actual problem.
As others have mentioned, no you cannot do this...technically. You can in fact achieve this effect through convert constructors and virtual functions.
If you write a convert constructor from A to B and B to A:
A::A(B convertFrom); // Convert from B to A
B::B(A convertFrom); // Convert from A to B
And you make the essential parts of each class virtual:
class base
{
virutal void baseClassFunction();
};
class A
{
virtual void baseClassFunction()
{
// Do things for A
}
};
Class B
{
virtual void baseClassFunction()
{
// Do things for B
}
}
Then you can simply make a pointer of type base which can hold a reference to either A or B.
Example bringing it all together;
int main()
{
base *ptr = new A();
bool needs_to_be_B;
...
// Program logic
ptr->baseClassFunction();
...
if(needs_to_be_B)
{
base *tmp = new B(*ptr);
delete ptr;
ptr = tmp;
delete tmp;
}
// ptr is now a B
ptr->baseClassFunction();
}
If you are confused look up virtual functions and convert constructors.

Invoking method in C++ [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
A question about C++ programming.
Can you do in C++ something like this:
Lecture le;
Carriage ca = le;
No casting, just writing like that. The problem is, when I am trying to invoke a method which belongs to Lecture class the methods is underlined in red.
ca.runIt();
I am not quite sure if I understood the specification of my task, but there is given this snippet of code. Best regards
Can you do in C++ something like this:
Yes.
struct Lecture {
};
struct Carriage {
Carriage(const Lecture&) {
}
void runIt() {
}
};
int main() {
Lecture le;
Carriage ca = le;
ca.runIt();
}
The problem is, when I am trying to invoke a method which belongs to Lecture class the methods is underlined in red.
Of course. ca isn't a Lecture. ca is a Carriage. You can only invoke Carriage methods on ca.
Let's break it down, from the general case to the most specific.
If you have some arbitrary class A and some other arbitrary class B, the statement:
A a;
B b = a;
is generally not going to work. It will certainly not work by itself; you have to put effort into making it work.
So now, let's get specific. If B is a class derived from A, then it will also not work. If A is derived from B, it will still not work.
Why? Because A a defines an object, not a reference. It creates a value. B b = a; is an attempt to store the value a into a new value b. You cannot do that.
If A is derived from B (B is the base class), you can do this:
A a;
B &b = a;
That's legal C++, and it's meaningful too. b now refers to part of a. Specifically, the part of a that is the base class.
Note that the reverse does not work. If A were the base class, C++ would raise an error.
Now, there is one way to make the general statement work.
A a;
B b = a;
If you want this to be reasonable for a specific class B, then B must be defined as follows:
class B ... //Whatever base classes you want.
{
public:
B(const A &a);
};
The constructor that takes a const A & is a conversion constructor. It's job is to create a B object using data from an a object. Because this conversion constructor was declared without the explicit keyword, then it can be used for implicit conversions like B b = a; If it were declared with the explicit keyword, you would have to explicitly convert it: B b = B(a);.
Having a conversion constructor on a class means that any instance of A can be converted into a B. So you can pass A to a function that takes a B (either by value or by const&. Not by reference) without having to do an explicit conversion.
Note that conversion constructing an object does not allow you to call functions from A on the object B. You can only call functions on B which B defines or are defined by one of B's base classes.

c++ access stuff out side the class [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 12 years ago.
ok, lets say I have this:
class A:
{
Public:
int dd;
}
Ok, then I have this class:
class B:
{
Public:
void sss(){ ff=dd; }
int ff;
}
Ok, the problem is that class B doesn't know what dd is. How can I make class B know it?
It's public: and not Public:.
Because dd is part of A, you need an instance of A to access dd.
The two classes aren't related in any way; since B does not have access to any A objects it can't take the value of its members.
If you were to pass an A object to the B constructor, either by value, reference, or pointer, you could access its dd member since you made it public.
You need to have an instance of A, and pass it to the sss method in order to access this data:
void sss(A a) { ff = a.dd; }
If you want to have only one copy of dd, rather than a single copy per instance of A, then you'll have to make dd static:
class A
{
public:
static int dd;
};
class B
{
public:
void sss() { ff = A::dd; }
int ff;
};
Maybe by passing in an A instance?
class B:
{
Public:
void sss(const A& a){ ff=a.dd; }
int ff;
}
Your code does not look like C++ but I will try to answer your question.
There would be several possibilities to do what you want. I just pick one which is easy to understand.
Do someting like this:
class B
{
public:
void sss() { ff = a.dd; }
int ff;
private:
A a;
};
However if you do not tell me what you really want to achieve with that class i.e. which responsibilites the class has this will not help you much.
The code that you present, ...
class A:
{
Public:
int dd;
}
class B:
{
Public:
void sss(){ ff=dd; }
int ff;
}
... is not valid C++.
You can find that out easily enough by trying to compile it. Then the compiler will complain about a lot of irrelevant things, but its first message will be related to the extraneous colon after A. When you remove that and compile again, its first message will be related to Public, as opposed to correct public (lowercase). So on.
Syntacically correct code (that will still produce a compilation error, but not about the basic syntax):
class A
{
public:
int dd;
};
class B
{
public:
void sss(){ ff=dd; }
int ff;
};
Imagine that you create five instances of class A, named a1, a2, a3, a4, and a5. Each such instance has a member dd, so you can refer to these five members as a1.dd, a2.dd, a3.dd, a4.dd, and a5.dd.
Now you create a B instance, naming it 'b'. And you call b.sss(). And that member function effectively does b.ff=dd. Or it would, had it been meaningful and accepted by the compiler. But it can't, for which of a1.dd, a2.dd, a3.dd, a4.dd, and a5.dd is being referred to?
So, since this is a very basic concept in C++, you need a good C++ textbook, such as Bjarne's latest, and start from the beginning.
Alternatively, since C++ is a very complicated programming language, it's probably even better to start with some simpler language, like Java, or even simpler, like JavaScript or Python. I recommend Python. It's very different from C++ in the details, but both languages are "conventional" programming languages. Using Python you'll learn about decision constructs and functions and things, including classes versus instances.
Cheers & hth.,