I am having a challenge calling methods from a direct parent Base class but I can call methods in the Base class 's parent with ease. To clarify what I mean here is the code:
First the structure of the opencascade library classes:
class TopoDS_Shape
{
public:
//..... a lot of methods like Closed(), Oriantable(), etc
};
class TopoDS_Face : public TopoDS_Shape
{
TopoDS_Face(); // implementation is like TopoDS_Face::TopoDS_Face(){}
}
In my code there are two types of topological faces Plane faces (ModelFace class) and NON-Planar faces (ModelBend class). These two faces share 6 attributes defined in the MFace class but only the ModelBend class has additional attributes of its own so I designed the system as follows
MFace class:
class MFace : public TopoDS_Face
{
FaceID mFaceID;
PlaneType mPlaneType;
FaceType mFaceType;
gp_Pnt mFaceNormal;
public:
void ModelFace::extractEdges()
{
for (TopExp_Explorer edgeEx((*this), TopAbs_EDGE); edgeEx.More(); edgeEx.Next())
{
TopoDS_Edge edge = TopoDS::Edge(edgeEx.Current());
ModelEdge edgex(edge);
addEdge(edgex);
}
}
// Setters and getters
// The OpenCascade Lib has a non-template method similar to this for converting a
// TopoDS_Shape to a face/edge/vertex/wire
template<typename T>
static T& toFace(TopoDS_Face& shape)
{
return *(T*) &shape;
}
};
ModelFace class:
class ModelFace : public MFace
{
ModelFace(); // implementation is like ModelFace::ModelFace(){}
void ModelFace::init(FaceID faceID) // WORKS LIKE A CHARM!!!
{
setFaceId(faceID);
std::cout << "ID : " << getFaceId() << '\n';
if (Closed()) {
std::cout << "Orr : " << Orientable() << '\n';
}
}
};
ModelBend class:
class ModelBend : public MFace
{
// Bend attributes : angles, radius, etc
ModelBend(); // implementation is like ModelBend::ModelBend(){}
// Setters and getters
// methods for computations
};
Usage : There is a Model class that represents a CAD model and stores all its topological ModelFace/ModelBend data. This class gets topological data in the form of a TopoDS_Shape and classifies it in the assignAttributes() as shown below :
void Model::assignFaceAttributes(const FaceID faceID, TopoDS_Shape& aShape)
{
// TODO : set the face attributes
TopoDS_Face pTopoDSFace = TopoDS::Face(aShape);
Standard_Real curvature = computeCurvature(pTopoDSFace);
if (curvature == 0.0){
std::cout << "Face" << '\n';
// Convert TopoDS_Face to ModelFace
ModelFace& pModelFace = MFace::toFace<ModelFace>(pTopoDSFace);
// This code work well : calls Orientable() in the TopoDS_Shape class
std::cout << "Orientable? : " << pModelFace.Orientable() << '\n';
// Works well
pModelFace.init(faceID);
// **PROGRAM CRASHES HERE!!!!!!!!!!!!!!**
pModelFace.extractEdges();
//...
} else {
// .....
std::cout << "Bend" << '\n';
// Convert TopoDS_Face to ModelBend
ModelBend& pModelFace = MFace::toFace<ModelBend>(pTopoDSFace);
//...
}
addFace(&pModelFace);
}
When I run the program it crashes on the call to pModelFace.extractEdges() in the assignAttributes() but when I copy the for loop in the extractEdges() method into the init() method it works fine.
My OOD/OOP ain't that good. May you please help me solve the problem and the why's of this behaviour. Thanks in advance.
This looks like a duplicate to your own other question:
Assigning a TopoDS_Face object to its child object compiles with no errors but I have 3 valgrind errors
TopoDS_Shape has no virtual methods (including no virtual destructor) and managed within OCCT by copy (e.g. not dynamically allocated). Adding class fields like you do in MFace will work only if you store object exactly like MFace - otherwise you are just casting a smaller in memory object TopoDS_Shape to a larger MFace leading to reading/writing to an uninitialized memory and crash.
The main difference between your MFace and TopoDS_Face is that TopoDS_Face defines NO new class fields nor virtual methods, which allows aliasing TopoDS_Shape to TopoDS_Face without side effects.
For instance:
void parseMFace (TopoDS_Shape& theFace)
{
MFace* anMFace = (MFace* )&theFace;
anMFace->doSomething();
}
int main()
{
MFace anMFace;
parseMFace (anMFace); // unsafe, but should work
TopoDS_Face aTFace;
parseMFace (aTFace); // will crash
TopoDS_Compound aComp;
BRep_Builder().MakeCompound (aComp);
BRep_Builder().Add (aComp, anMFace); // here MFace will be truncated to TopoDS_Shape
for (TopoDS_Iterator aFaceIter (aComp); aFaceIter.More(); aFaceIter.Next()
{
TopoDS_Face& aTFace2 = TopoDS::Face (aFaceIter.Value());
parseMFace (aTFace2); // will crash, because TopoDS_Compound does not store MFace
}
std::vector<MFace> anMFaces;
anMFaces.push_back (anMFace);
parseMFace (anMFaces[0]); // OK, but unsafe
}
Related
I have a struct A that inherits from other classes (which I'm not allowed to change). Inside A and it's methods I can call inherited methods (lets say A_method(int i), for example) without problem but when I tried to write a nested struct (lets say In) and call A_method(int i) and there is were I'm stuck.
The initial code looks like this, and I can't change it, is some kind of college assigment.
#include "Player.hh"
struct A : public Player {
static Player* factory () {
return new A;
}
virtual void play () {
}
};
RegisterPlayer(PLAYER_NAME);
Then I tried this:
#include "Player.hh"
struct A : public Player {
static Player* factory () {
return new A;
}
//My code
struct In {
int x;
void do_smthing() {
A_method(x);
}
}
virtual void play () {
}
};
RegisterPlayer(PLAYER_NAME);
Ok, from a beginning I knew I could't do this, for In to see it's parent class it should have a pointer to it but In is a often instantiated object in my code and I wanted to avoid passing this constantly to a constructor so I tried this aproach:
#include "Player.hh"
struct A : public Player {
static Player* factory () {
return new A;
}
//My code
static struct Aux
A* ptr;
Aux(A* _p) { ptr = _p; }
} aux;
struct In {
int x;
void do_smthing() {
aux.ptr->A_method(x);
}
}
virtual void play () {
//the idea is to call do_smthing() here.
}
};
RegisterPlayer(PLAYER_NAME);
What I want to avoid (if possible) is something like this:
struct In {
int x;
A* ptr;
In (A* _p) : ptr(_p) {}
void do_smthing() {
ptr->A_method(x);
}
}
The main reason for this: I have more struct definitions and they they are instantiated multiple times through the rest of the (omitted) code, and I don't like the idea of seeing In(this) so many times.
I don't know if I'm completly missing something or what I want to do it's just not possible... Please ask for clarifications if necessary.
(Also, performance is kind of critical, my code will be tested with limited CPU time so I kinda have to avoid expensive approachs if possible. Using C++11)
There is no way you can skip passing the this pointer. Instead, you could create a helper function in A:
template <typename InnerType, typename ...Params>
InnerType makeInner(Params&&... params)
{
return InnerType(this, std::forward<Params>(params)...);
}
Then you can use
auto * a = A::factory();
auto inner = a->makeInner<A::In>();
I have some suggestions which are not directly related to you question but may help:
A::facotry() returns a std::unique_ptr<A> instead of raw pointer
Try to describe what problem you are trying to solve. I have a strong feeling that there can be a better design other than creating many nested structs.
I don't see passing a this pointer could have any impact on the performance. The more important thing is to identify the path that is latency-sensitive and move expensive operations out of those paths.
The crux of the issue is I want to create a vector of base pointers to reference children objects. However I'm having issues accessing the methods of the children. I've seen examples of downcasting online but I don't feel it's the best thing for me since I want to keep my code generic. Please look below for a sample of what I'm trying to accomplish.
class Base
{
public:
stuffx;
private:
stuffy;
}
template<typename U>
class Child : public Base
{
public:
Child(
std::function<U()> getterFunc,
std::function<void(U)> setterFunc
):
mgetter(getterFunc),
msetter(setterFunc)
{
}
U getFunction() const {return m_getter();}
void setFunction(U input) const {return m_setter(input);}
private:
observableValues() {}
std::function<U()> m_getter;
std::function<void(U)> m_setter;
}
int main()
{
std::vector<std::shared_ptr<Base>> Dummy = {std::make_shared<Child<int>> (std::bind(..), std::bind(...)),
std::make_shared<Child<string>> (std::bind(..), std::bind(...)) };
Dummy.at(0)->getGFunction(); // this throws an error as out of scope.
(dynamic_cast<Child<int>>(Dummy.at(0))->getGFunction(); // this is ok
}
In this example above my vector is of size 2 which is manageable but my goal is to serialize c++ classes to a psql server and may have to handle vectors of size 30+. My next question is is there a way to automate this in a for loop taking into the account the type deduction that may need to be performed for typename U.
int main()
{
std::vector<std::shared_ptr<Base>> Dummy = {std::make_shared<Child<int>> (std::bind(..), std::bind(...)),
std::make_shared<Child<string>> (std::bind(..), std::bind(...)) };
std::vector<std::shared_ptr<Base>>::const_iterator it_base = Dummy.begin();
for (; it_base != Dummy.end(); ++it_base)
{
//insert method here for downcasting
}
}
There is a custom defined map, with an element std::function()>.
The lambda code is working, but I don't know how to expand it to a normal formation. The code is following.
class TestA{
public:
TestA() {}
~TestA() {}
TestA(const TestA &) {}
static void print()
{
cout << __FUNCTION__ << endl;
return;
}
};
void testComplexMap1()
{
typedef map<string, std::function<std::unique_ptr<TestA>()>> TempMap;
TempMap m;
// the lambda format code, it works
//m.insert({ "TestA", []() {return std::unique_ptr<TestA>(new TestA());}});
// I want to expand it, but failed.
TestA *t = new TestA();
//function<unique_ptr<TestA>()> fp(unique_ptr<TestA>(t));
function<unique_ptr<TestA>()> fp(unique_ptr<TestA>(t)()); //warning here
//m.emplace("TestA", fp); // compile error here
}
Any help will be greatly appreciated.
fp is not initialized with a function so compilation fails.
You can expand it like this:
TestA *t = new TestA();
std::unique_ptr<TestA> UT(t);
auto func = [&]() { return move(UT);};
std::function<std::unique_ptr<TestA>()> fp(func);
m.emplace("TestA", fp);
See DEMO.
In C++ everything that looks like it could be a declaration is treated as such.
This means the line
function<unique_ptr<TestA>()> fp(unique_ptr<TestA>(t)());
is interpreted as:
fp is the declaration of a function returning an std::function<unique_ptr<TestA>()> and expecting a parameter called t which is a function pointer to a function returning a std::unique_ptr<TestA> and getting no parameter. (Which is not what you intended.)
This also means that the t in this line is not the same t as in the previous line.
You have to pass fp something that is actually callable like this:
std::unique_ptr<TestA> f() {
return std::make_unique<TestA>();
}
void testComplexMap1() {
// ...
function<unique_ptr<TestA>()> fp(f);
m.emplace("TestA1", fp);
}
If you want to add a function to the map that wraps an existing pointer into a unique_ptr you would need either a functor:
class Functor {
public:
Functor(TestA * a) : m_a(a) {}
~Functor() { delete m_a; }
std::unique_ptr<TestA> operator()(){
auto x = std::unique_ptr<TestA>(m_a);
m_a = nullptr;
return std::move(x);
}
private:
TestA * m_a;
};
void testComplexMap1() {
//...
TestA * t = new TestA();
m.emplace("TestA", Functor(t));
}
Or a lambda with capture:
void testComplexMap1() {
//...
TestA * t = new TestA();
m.emplace("TestA", [t](){ return std::unique_ptr<TestA>(t); });
}
The lamda is translated more or less to something like the Functor class. However in each case you have to be really careful: The functions in the map that encapsulate an existing pointer into a std::unique_ptr can and should only be called once.
If you don't call them, memory allocated for t won't be freed. If you call them more than once you get either a std::unique_ptr to nullptr (in my Functor class variant) or a more than one std::unique_ptr tries to manage the same memory region (in the lambda with capture variant), which will crash as soon as the second std::unique_ptr is deleted.
In short: I would advice against writing code like this and only put functions in the map that are callable multiple times.
I'm working with OpenMp and I need to copy an instance of a class N times (one for each thread). I'm using inheritance to create my struct of data. For example:
// Super class
class vehicle {
private:
// general attributes of any vehicle
.......
}
// Sub class
class car : public vehicle {
private:
// some specific attributes of a car
string color;
......
public:
car(string color);
car(car _car);
void change_color(string color);
}
If I have 4 threads, I need to have 4 instance of the car but I would like that this 4 instances shares the same specific data of the super class (only one copy in memory). For example, if I have the follow code:
int main() {
.....
string colors[] = {"green", "blue", "red", "orange"};
.....
car base_car = new car(colors[0]);
car cars[4];
for ( int i = 0; i < 4; i++ ) {
cars[i] = new car(base_car);
}
....
int thread_id;
#pragma omp parallel private (thread_id)
thread_id = omp_get_thread_num();
car thread_car = cars[thread_id];
thread_car.change_color(colors[thread_id]);
}
I'd like that the instances of the car in the cars array share the attributes of the super class vehicle, that is to say, I would like to have only one copy of the data (in memory) of the attributes of the super class vheicle and 4 copy of the data of the derived class car.
This is possible?
Thank you.
I have the following base class:
class node_layer_manager_t : public layer_manager_t
{
protected:
//Devices
trx_t trx;
private:
std::vector<string> trx_dump_labels;
public:
node_layer_manager_t( xml::node_t& params );
~node_layer_manager_t();
virtual bool set_profile(void) override;
}
I created the following derived class:
class node_layer_manager_with_rad_t : public node_layer_manager_t
{
protected:
//Devices
radio_t radio;
public:
node_layer_manager_with_rad_t(xml::node_t& params );
~node_layer_manager_with_rad_t();
virtual bool set_profile(void) override;
virtual void radio_monitoring_job_function(void);
intervalues_t<double> radio_tmp;
ushort duration_seconds_for_radio_monitoring;
};
I want it so that the set profile will execute the set_profile of the base class and in addition some other action.
Can I just write it this way?
bool node_layer_manager_with_rad_t::set_profile(void)
{
bool success;
node_layer_manager_t::set_profile();
try
{
string_t profile_tag = "logs/trx_dump/node:"+get_id();
dev_tx = profile->get_decendant(profile_tag.c_str());
cout<<"sarit id= "<< get_id()<<endl;
success = true;
}
catch(...)
{
cout<<"sarit profile error: "<<endl;
success = false;
}
return success; //**
}
**Or should I reurn the follwing:
return (success && node_layer_manager_t::set_profile());
If you have to call parent set_profile regardless what you have to do in derived class, you should adopt design which take care about this constraint.
Typically, you should mark based class set_porfile as final and manage call of a dedicated derived class method inside based class:
class node_layer_manager_t : public layer_manager_t
{
protected:
....
// set_profile actions of derived class
// proposed a default without side effect implementation if
// derived class doesn't need to overload this.
virtual bool set_profile_child() { return true; };
private:
....
public:
.....
// Manage here call of derived
virtual bool set_profile() override final
{
// actions before derived specific actions
....
// Call specific derived class actions
bool success = set_profile_child();
// actions after derived specific actions
if (success)
{
//do based class action
}
return success;
}
}
and in child:
class node_layer_manager_with_rad_t : public node_layer_manager_t
{
protected:
....
public:
virtual bool set_profile_child() override;
};
// Manage only there own action, regardless of needs of based class
bool node_layer_manager_with_rad_t::set_profile(void)
{
try
{
// Do what you're in charge, and only what you're in charge!
}
catch(...)
{
cout<<"sarit profile error: "<<endl;
success = false;
}
return success; //**
}
With this kind of design, each class do only what it have to manage, and only its. Derived class doesn't have to deal with needs of based class.
If you want to offer to your derived class ability to decided if code is executed before or after generic behavior, you can replace or add to set_profile_child() two methods: bool pre_set_profile() and bool post_set_profile()
At first, you haven't declared success anywhere (so actually, this is not a mcve, the code should not compile as is).
Still I get it - and tThe answer is: it depends on what you actually want to do...
Do you want to call the super class first or after the sub class code? Your example implies the former, your alternative the latter. Do you want to abort if the super class function fails or still execute your code?
Your inital example calls the super class function, ignores the result and does its own stuff afterwards.
This calls the super class function first and continues only on success:
bool success = node_layer_manager_t::set_profile();
if(success)
{
try { /*...*/ } // <- no need to set success to true, it is already
catch(...) { /*...*/ success = false; }
}
This executes both, but combines the result:
bool success = node_layer_manager_t::set_profile();
try { /*...*/ } // <- do not modify success, must remain false if super class failed!
catch(...) { /*...*/ success = false; }
Your alternative hints to executing the sub class code first and only call the super class function, if nothing went wrong.
Any of these approaches might be appropriate, none of them might be. You have to get a clear image of what your requirements are - and then implement the code such that your needs are satisfied...