Looking for how to best access class B's queue through A but I am receiving a segmentation fault. Also I am looking for the best way to communicate between these two classes. Are accessor methods ok in this scenario? What design pattern could work? Thanks
class B {
public:
int get_int() { return qi.front(); }
void put_int(int i) { qi.push(i); }
private:
queue<int> qi;
};
class A
{
public:
void get_event() { cout << b->get_int() << endl; }
void put_event(int a) { b->put_int(a); }
private:
B *b;
};
int main() {
A a;
a.put_event(1);
return 0;
}
As mentioned in comment problem is undefined initialization
you can fix that by using constructor for initialization
#include<iostream>
#include<queue>
using namespace std;
class B {
public:
int get_int() { return qi.front(); }
void put_int(int i)
{
qi.push(i);
}
private:
queue<int> qi;
};
class A
{
public:
void get_event() { cout << b->get_int() << endl; }
void put_event(int a) { b->put_int(a); }
A()
{
b = new B();
}
~A() { delete b; }
private:
B *b;
};
int main() {
A a;
a.put_event(1);
a.get_event();
return 0;
}
Output
1
Program ended with exit code: 0
A a;
is an undefined reference, you have to initialize it with a costructor and since you didn't defined any, you must use the default one
A a=new A();
or better, write the costructors of the two classes as you prefer and use them.
Related
In C ++, I first encountered function pointers.
I tried to use this to make it similar to Action and Delegate in C #.
However, when declaring a function pointer, it is necessary to specify the type of the class in which the function exists.
ex) void (A :: * F) ();
Can I use a function pointer that can store a member function of any class?
In general, function pointers are used as shown in the code below.
class A {
public:
void AF() { cout << "A::F" << endl; }
};
class B {
public:
void(A::*BF)();
};
int main()
{
A a;
B b;
b.BF = &A::AF;
(a.*b.BF)();
return 0;
}
I want to use it like the code below.
is this possible?
Or is there something else to replace the function pointer?
class A {
public:
void AF() { cout << "A::F" << endl; }
};
class B {
public:
void(* BF)();
};
int main()
{
A a;
B b;
b.BF = a.AF;
return 0;
}
I solved the question through the answer.
Thanks!
#include <functional>
#include <iostream>
class A {
public:
void AF() { std::cout << "A::F" << std::endl; }
};
class C {
public:
void CF() { std::cout << "C::F" << std::endl; }
};
class B {
public:
B(){}
std::function<void()> BF;
};
int main() {
A a;
C c;
B b;
b.BF = std::bind(&A::AF, &a);
b.BF();
b.BF = std::bind(&C::CF, &c);
b.BF();
int i;
std::cin >> i;
return 0;
}
What you want to do is probably something like this. You can use std::function to hold a pointer to a member function bound to a specific instance.
#include <functional>
#include <iostream>
class A {
public:
void AF() { std::cout << "A::F" << std::endl; }
};
class B {
public:
B(const std::function<void()>& bf) : BF(bf) {}
std::function<void()> BF;
};
int main() {
A a;
B b1(std::bind(&A::AF, &a)); // using std::bind
B b2([&a] { a.AF(); }); // using a lambda
b1.BF();
b2.BF();
return 0;
}
Here's a C# style implementation of the accepted answer, It is memory efficient and flexible as you can construct and delegate at different points of execution which a C# developer might expect to do:
#include <iostream>
#include <functional>
using namespace std;
class A {
public:
void AF() { cout << "A::F" << endl; }
void BF() { cout << "B::F" << endl; }
};
class B {
public:
std::function<void()> Delegate;
};
int main() {
A a;
B b;
b.Delegate = std::bind(&A::AF, &a);
b.Delegate();
b.Delegate = [&a] { a.BF(); };
b.Delegate();
return 0;
}
I'm looking to do something only if the class is a specific derived class. That is I have:
class X{
int id;
}
class A: public X{
void run();
}
class B: public X{
int lala;
}
And I want to do something along the line of:
main(){
vector<X *> types;
types.push_back(new A);
types.push_back(new B);
int var = 0;
for(int i = 0; i<types.size(); i++){
if(types[i].isType(A)) {types[i].run();}
}
for(int i = 0; i<types.size(); i++){
if(types[i].isType(B)) {var = lala;}
}
}
I do not want class B to have anything equivalent to run(), nor do I want class A to have an equivalent to lala.
I know fortran has a workaround with
select type ( x => var )
class is ( A )
x.run()
end select
But I wasn't sure what my options in C++ were.
Thanks
You are looking for dynamic_cast.
#include <vector>
using namespace std;
class X {
public:
int id;
virtual ~X() = default;
};
class A : public X {
public:
void run() {}
};
class B : public X {
public:
int lala;
};
main(){
vector<X *> types;
types.push_back(new A);
types.push_back(new B);
int var = 0;
for(int i = 0; i<types.size(); i++){
if (auto ta = dynamic_cast<A *>(types[i])) {
ta->run();
}
}
for(int i = 0; i<types.size(); i++){
if (auto tb = dynamic_cast<B *>(types[i])) {
var = tb->lala;
}
}
}
Also see it in action here: https://onlinegdb.com/B1d29P5if.
I had to fix a few other problems with the code. Since they are not a part of your question, I won't clarify here, but you are welcome to ask if something is not clear.
EDIT: The above solution has memory leaks, which I didn't fix, as it wasn't required by the question. For completeness, here is the main function with memory leaks fixed (https://onlinegdb.com/ByeOmu9iz):
int main() {
vector<unique_ptr<X>> types;
types.emplace_back(new A);
types.emplace_back(new B);
int var = 0;
for(int i = 0; i < types.size(); ++i) {
if (auto ta = dynamic_cast<A *>(types[i].get())) {
ta->run();
}
}
for(int i = 0; i < types.size(); ++i) {
if (auto tb = dynamic_cast<B *>(types[i].get())) {
var = tb->lala;
}
}
}
Note that this is a C++11 solution.
If you're working with an even older compiler, you'll have to keep using plain pointers as in the original solution, and deallocate the memory manually at the end by calling delete on each element of the vector. (And hope nothing throws an exception before you reach that step.)
You'll also have to replace auto ta with A* ta and auto tb with B* tb.
A modern C++17 solution to this problem is to use a vector of variants, i.e. std::vector<std::variant<A, B>>. You need a modern compiler for this.
Here is a complete example, based on the std::variant documentation:
#include <vector>
#include <variant>
#include <iostream>
class X {
int id;
};
class A: public X {
public:
void run() {
std::cout << "run\n"; // just for demonstration purposes
}
};
class B: public X {
public:
B(int lala) : lala(lala) {} // just for demonstration purposes
int lala;
};
int main() {
std::vector<std::variant<A, B>> types;
types.push_back(A()); // no more new!
types.push_back(B(123)); // no more new!
int var = 0;
for (auto&& type : types) {
std::visit([&](auto&& arg) {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, A>) {
arg.run();
} else {
var = arg.lala;
}
}, type);
}
std::cout << var << '\n'; // just for demonstration purposes
}
As a nice bonus, this solution elegantly gets rid of dynamic allocation (no more memory leaks, no smart pointers necessary).
I have two ideas....
Why not have a shared method that returns a value that gives context as to whether or not it is an A or B? If for example, lala is expected to return only values 0 or greater, you could have void run() instead be int run() and return -1 at all times.
class X {
int id;
virtual int run() = 0; //Assuming X isn't meant to be instantiated
}
class A: public X {
// Return -1 to differentiate between As and Bs
int run() { return -1; }
}
class B: public X {
int lala;
int run() { return lala;}
}
Then you have...
main(){
vector<X *> types;
types.push_back(new A);
types.push_back(new B);
int var = 0, temp = 0;
for( int i = 0; i<types.size(); i++ ) {
if( (temp = types[i].run()) != -1 )
var = temp;
....
}
}
Again, only works if lala would never expect to return a particular range of values.
You could also hide information in X, upon creation of an A or B to keep track of what you have.
class X {
int id;
bool isA;
}
class A: public X {
A() : isA(true) { };
void run();
}
class B: public X {
B() : isA(false) { } ;
int lala;
}
Then you have...
main(){
vector<X *> types;
types.push_back(new A);
types.push_back(new B);
int var = 0;
for( int i = 0; i<types.size(); i++ ) {
if( types[i].isA == true ) {
types[i].run();
}
else {
var = types[i].lala;
}
}
Naturally if you expect to add C, D, E, .... it will no longer be worth it, but for only two derived classes it isn't all that bad.
I would justify this based on the fact that users are already going to have to peer into the derived classes to see why they behave so differently for being derived from the same class. I would actually look into whether or not it makes sense for A and B to derive from X based on their interface.
I also wouldn't recommend dynamic_cast(ing) without informing someone that it's one of the more dangerous casts to perform and typically not recommended.
You could use dynamic_cast to check if the base class pointer is convertible to a derived instance.
Another option would be to have a virtual function that returns the typeinfo of the class and thus use that information to cast the pointer to a convertible type. Depending on how dynamic_cast is implemented this could be more performant. Thus, you could use this if you want to try and see whether or not this method is quicker on your platform.
As #Jarod42 noted, you would need to have a virtual function, destructor in this case, for dynamic_cast to work. In addition, you would simply need a virtual destrctor to avoid undefined behavior when deleting the instance.
Example
#include <iostream>
#include <string>
#include <vector>
#include <typeinfo>
struct A {
virtual ~A() {
}
virtual const std::type_info& getTypeInfo() const {
return typeid(A);
}
};
struct B : public A {
virtual const std::type_info& getTypeInfo() const override {
return typeid(B);
}
};
struct C : public A {
virtual const std::type_info& getTypeInfo() const override {
return typeid(C);
}
};
int main()
{
std::vector<A*> data;
data.push_back(new A);
data.push_back(new B);
data.push_back(new C);
for (auto& val : data) {
if (val->getTypeInfo() == typeid(A)) {
std::cout << "A";
}
else if (val->getTypeInfo() == typeid(B)) {
std::cout << "B";
}
else if (val->getTypeInfo() == typeid(C)) {
std::cout << "C";
}
std::cout << std::endl;
}
for (auto& val : data) {
delete val;
}
}
I'm looking for a design pattern which can store vector of pointers and can remove the vector of pointers based on the demand.
This is my existing code path.
### implementation.h
class A {
A() {}
private:
void AggregateMetrics();
void FlushMetrics();
X* x_;
Y* y_;
};
class X {
public:
void CreateFiles(vector<B*> *objects, string path);
};
class B {
B() {
m_ = 0, n_ = 0;
}
private:
int m_, n_;
};
### implementation.cpp
void A::A() {
x_ = new X();
y_ = new Y();
}
void A::AggregateMetrics() {
}
void A::FlushMetrics () {
vector<B*> objects;
x_->CreateFiles(&objects, path);
// In my new code, we are going to move the above two lines
// to AggregateMetrics() and i need to find a way to store
// the vector<B*>objects;
y_->Flush(objects);
return;
}
void X::CreateFiles(vector<B*> *objects, string path) {
CHECK(objects.empty());
for (int i = 0; i < 10; i++) {
objects->push_back(new B());
}
}
Here is my new code:
### implementation.h
class A {
A() {}
private:
void AggregateMetrics();
void FlushMetrics();
X* x_;
Y* y_;
};
class X {
public:
void CreateFiles(vector<B*> *objects, string path);
};
class B {
B() {
m_ = 0, n_ = 0;
}
private:
int m_, n_;
};
class PointerManager {
public:
PointerManager() {}
void SetPointers(vector<B*>& objects);
vector<B*> GetPointers();
private:
vector<B*>objects_;
};
### implementation.cpp
PointerManager::SetPointers(vector<B*>& objects) {
objects_ = objects;
}
vector<B*> PointerManager::GetPointers() {
return objects_;
}
void A::A() {
x = new X();
y = new Y();
mgr_ = new PointerManager();
}
void A::AggregateMetrics() {
vector<B*> objects;
x->CreateFiles(&objects, path);
mgr_->SetPointers(objects);
}
void A::FlushMetrics () {
auto objects = mgr_->GetPointers();
y->Flush(objects);
return;
}
void X::CreateFiles(vector<B*> *objects, string path) {
CHECK(objects.empty());
for (;;) {
objects->push_back(new B());
}
}
I'm basically creating a new class called PointerManager which can hold these pointers after the creation and can return when needed. What would be the ideal design here? Can you guys suggest a design pattern?
I suggest using smart pointer and store them into a container to avoid any memory leak.
Here's the version of your design using smart pointer
implementation.hpp :
#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <cassert>
class B {
public:
B() {
m_ = 0, n_ = 0;
}
private:
int m_, n_;
};
class Y{
public:
Y(){}
~Y(){}
void Flush(std::vector<std::unique_ptr<B>>& objects);
};
class X {
public:
void CreateFiles(std::vector<std::unique_ptr<B>> &objects, std::string path);
};
class PointerManager {
public:
PointerManager() {}
void InsertPointer(std::unique_ptr<B> &object);
void SetPointers(std::vector<std::unique_ptr<B>> &objects);
std::vector<std::unique_ptr<B>> &GetPointers();
private:
std::vector<std::unique_ptr<B>> objects_;
};
class A {
public:
A();
void AggregateMetrics();
void FlushMetrics();
private:
X* x_;
Y* y_;
PointerManager* mgr_;
};
implementation.cpp
#include "implementation.hpp"
void Y::Flush(std::vector<std::unique_ptr<B>>& objects){
for(int i =0;i<objects.size();i++){
objects[i].release();
}
}
void X::CreateFiles(std::vector<std::unique_ptr<B>> &objects, std::string path) {
assert(objects.empty());
for (int i = 0; i < 5;i++) {
std::cout << "for loop in CreatesFiles " << std::endl;
objects.emplace_back(new B);
}
}
void PointerManager::InsertPointer(std::unique_ptr<B> &object) {
std::cout << "InsertPointer " << std::endl;
objects_.push_back(std::move(object)); // object now belongs to PointerManager
}
void PointerManager::SetPointers(std::vector<std::unique_ptr<B>> &objects){
for(int i=0;i<objects.size();i++){
this->InsertPointer(objects[i]);
}
}
std::vector<std::unique_ptr<B>>& PointerManager::GetPointers() {
std::cout << "Get Pointers" << std::endl;
return objects_;
}
A::A() {
x_ = new X();
y_ = new Y();
mgr_ = new PointerManager();
}
void A::AggregateMetrics() {
std::cout << "Aggregate Metrics " << std::endl;
std::string path = ".";
std::vector<std::unique_ptr<B>> objects;
x_->CreateFiles(objects, path);
mgr_->SetPointers(objects);
}
void A::FlushMetrics () {
std::cout << "Flush Metrics " << std::endl;
y_->Flush(mgr_->GetPointers());
return;
}
This run fine with CLANG 3.4.2 and g++ 4.9.3 using -std=c++11 flag.
What you are basically asking is: "how do I implement my own memory management using raw pointers?"
And the answer to that is: you don't.
Modern day C++ offers concepts such as smart pointers or unique/shared pointers that take a lot of that "management" burden from the shoulders of your application code.
So the real answer here is: step back, and learn how to use C++ with all the means that are available in 2017; instead of writing code that would have been written like that 15, 20 years ago.
#include <iostream>
using namespace std;
class armon {
int a;
int b;
public:
armon(int newA, int newB) : a(newA), b(newB) {}
armon setA(int newA) {
a = newA;
return *this;
}
armon setB(int newB) {
b = newB;
return *this;
}
void print(void) { cout << a << endl << b; }
};
int main() {
armon s(3, 5);
s.setA(8).setB(9);
s.print();
}
Why can't i just return the object with the this pointer to make
cascaded function calls?
Why do i need to return the reference of the object?
What would that even do?
Returning this pointer would be sufficient, too. However, the syntax of cascaded invocation would need to change in the middle of the chain:
s.setA(8)->setB(9)->setC(10);
This does not look consistent, so returning a reference is a better choice.
Here is a complete example.
I want to forbid using A::set from objects casted from B to A by allowing only casting
B to const A.
How to do it?
(I can't use virtual functions)
#include <iostream>
#include <cassert>
using namespace std;
class A {
public:
int get() const { return i_; }
void set(int i) { i_ = i; }
protected:
int i_;
};
class B : public A {
public:
int ok() const { return A::get() == copy_i_; }
void set(int i) { A::set(i); copy_i_ = i; }
protected:
int copy_i_;
};
void test2() {
A a;
a.set(3); // ok here
cout << a.get() << endl;
B b;
b.set(5);
A& aa = b;
assert(b.ok());
aa.set(3); // not ok here
assert(b.ok()); // fail-here
}
int main() {
test2();
return 0;
}
You could make the inheritance private and provide a member function in B to use instead of casting.
const A& B::convert_to_A() const { return *this; }
Why casting? Making void A::set(int i) protected will work in your case.
There is no need for forbidding non-const casts. You can solve your problem by using the template method design pattern.
#include "stdafx.h"
#include <iostream>
#include <cassert>
using namespace std;
class A {
public:
int get() const { return i_; }
void set(int i) { assert(i_ = i); copy_i();}
protected:
int i_;
virtual void copy_i(){};
};
class B : public A {
public:
int ok() const { return A::get() == copy_i_; }
protected:
int copy_i_;
void copy_i(){copy_i_ = i_; }
};
void test2() {
B b;
b.set(5);
A& a = b;
assert(b.ok());
a.set(3);
assert(b.ok()); // success!
}
int main() {
test2();
return 0;
}