I am using a pointer of abstract type that is inherited from a base class.
Currently, each subclass must include the following behaviour in their constructor:
p = &f; //where p is the inherited pointer and f is the subclass filter
Naturally, I wish to move this behaviour up to the base class but I'm struggling to get this work. I'm not sure whether this is due how I am declaring types or if I need to change the implementation to reflect the movement of the behaviour (or something else!).
I've essentially tried to copy this line and call the base constructor through the subclass constructor:
//base.h
class Base {
pcl::Filter<pcl::PointXYZRGB>* f;
public:
Base(pcl::Filter<pcl::PointXYZRGB> abs_filter);
};
//base.cpp
Base::Base(pcl::Filter<pcl::PointXYZRGB> abs_filter) { f = &abs_filter; }
//subclass.h
class Subclass: public Base {
pcl::VoxelGrid<pcl::PointXYZRGB> vg;
public:
Subclass(void);
};
//subclass.cpp
Subclass::Subclass(void): Base(vg) { }
This will not compile and produces the following error:
error: cannot declare parameter ‘abs_filter’ to be of abstract type ‘pcl::Filter<pcl::PointXYZRGB>’
I tried to take the address pcl::Filter<pcl::PointXYZRGB> &abs_filter and change the method to f = abs_filter; but this also doesn't compile, reporting the following:
error: cannot convert ‘pcl::Filter<pcl::PointXYZRGB>’ to ‘pcl::Filter<pcl::PointXYZRGB>*’ in assignment Base::Base(pcl::Filter<pcl::PointXYZRGB> &abs_filter) { f = abs_filter; }
Where am I going wrong in what I am doing?
Any help is much appreciated!
When defining a function having a parameter passed by value, this is what happens
int myFun(myClass x) {
// x exists only in this function
// because is a copy of the argument passed to x
}
So change
Base(pcl::Filter<pcl::PointXYZRGB> abs_filter) { f = &abs_filter; }
to
Base(pcl::Filter<pcl::PointXYZRGB>& abs_filter) { f = &abs_filter; }
Not to get a copy of it, to pass the value itself.
You are setting f to a pointer to a local variable - that will not work (the abs_filter is a local copy of the vg-variable). Use one of the following:
Base::Base(pcl::Filter<pcl::PointXYZRGB>&abs_filter) { f = &abs_filter;}
Base::Base(pcl::Filter<pcl::PointXYZRGB>*abs_filter) { f = abs_filter; }
(with corresponding change in classes).
Related
My parent class holds two functions: On is supposed to be overwritten by the child, the second (same name) just uses as input a different type and than uses the overwritten method. Now I understand that if I define in the child class a method with the same name and same input parameters, it will shadow (is that the right expression?) the parents method. But I can still call the parents method by calling it explicit like: b.A::getSize(...).
My question is: Why does the parent method get shadowed even if the input parameter types are different? Why can't the compiler find the parent method with the correct input types? See the below minimal example.
And bonus question: Is it possible to achieve the behaviour that I can call the parents method without the need of the explicit call and without modifying main(){...} nor class B{...}; nor using different names?
#include <cstdio>
class A{
public:
virtual void getSize(size_t &i) = 0;
void getSize(int &d){
size_t i;
getSize(i);
d = static_cast<int>(i);
}
};
class B : public A{
public:
void getSize(size_t &i) override{
i = 4;
}
};
int main(){
size_t t;
int i;
B b;
b.getSize(t);
b.getSize(i); // error: non-const lvalue reference to type 'size_t' (aka 'unsigned long') cannot bind to a value of unrelated type 'int'
b.A::getSize(i); // this works but is not acceptable (too much changes in production code)
printf("%zu, %d",t,i);
return 0;
}
You can choose to expose the method with a using statement:
class B : public A
{
// ...
using A::getSize;
}
In your code snippets, you have used uninitialised values in many places, this invokes UB.
I am trying something new and am hoping some veterans can guide me in the right path. I did research but couldn't quite find the answer.
I am trying to declare a function pointer using the constructor of a class. I am receiving the error:
cannot convert 'int(**)()' to 'int(*)()' in assignment
Here is my code:
class A
{
public:
A(int (*ptr1)());
void update();
private:
int (*_ptr2)();
};
A::A(int(*ptr1)()){
_ptr2 = &ptr1;
}
void A::update()
{
int result = _ptr2();
}
You want just
_update_method = func;
there, without the &.
_update_method = &func;
actually takes the address of the int(*func)() parameter, not the function pointer passed. Hence the compiler correctly complains that the types don't match.
What is the advantage (if one exists) to assigning a variable in the header of a function or constructor? In other words, what is the difference between the following two sets of code and why would I prefer one over the other?
Example 1:
class A {
private:
char* b;
public:
A(size_t var = 8*1024*1024) {
...
b = new char[var];
...
}
...
};
Example 2:
class A {
private:
char* b;
public:
A() {
const size_t var = 8*1024*1024;
...
b = new char[var];
...
}
...
};
I appreciate any constructive input.
That is a default argument. It allows the caller to call the function without passing an argument, in which case the default value is used.
So in the first example, one could call:
A* myADefault = new A(); // creates A with default value (8*1024*1024)
A* myLargerA = new A(16*1024*1024); // creates A passing 16*1024*1024 instead of the default
(for more info, look at the "Default values in parameters" section in this tutorial: http://www.cplusplus.com/doc/tutorial/functions2/)
It's really different.
The first represents a default value, that means you can declare A test or A test2(42). In test, b will have a size of 8*1024*1024. In test2, b will have a size of 42.
The second snippet is just a constante value.
You will prefere one to other depending on your needs ...
This is a so called default argument: http://msdn.microsoft.com/en-us/library/91563f79(v=vs.80).aspx
The difference is that you can set value for the the var in the first case but not in the second case.
What you've wrote are two different beings : in the first example, var is an input parameter with a default value of 8*1024*1024 while in the second, it is a local const variable. Even if the behaviour is the same, the inner structure isn't.
To anwser your question about the preference of one method over the other, it depends on your design : the former add some flexibility, but also expose a parameter which maybe should stay hidden, while the latter is more rigid, but also less error-prone.
But neither case is particularly good. Member variables should be initialized in constructor initialization lists. That is the only way to initialize a const member variable, for example.
class A {
private:
char* b;
public:
A(size_t var = 8*1024*1024): b(new char[var]) {
...
}
~A() {
delete [] b;
}
};
Even then, a smart pointer would be better for b.
I'm having a class with 2 pure virtual methods and another class which needs to use an object of this class. I want to allow the user of this class to specify which derivation of the abstract class should be used inside of it.
I'm struggling to figure out what the right way is.
struct abstract {
virtual int fst_func() = 0;
virtual void sec_func(int) = 0;
};
// store an instance of "abstract".
class user_of_abstract
{
private:
abstract* m_abstract;
public:
// Pass a pointer to an "abstract" object. The caller takes care of the memory resource.
user_of_abstract_base(abstract* a) : m_abstract(a) { }
// Pase any type, which needs to be derived from "abstract" and create a copy. Free memory in destructor.
template<class abstract_type>
user_of_abstract_base(abstract_type const& a) : m_abstract(new abstract_type(a)) { }
// use the stored member to call fst_func.
int use_fst_func() {
return this->m_abstract->fst_func();
}
// use the stored member to call sec_func.
void use_sec_func(int x) {
this->m_abstract->sec_func(x);
}
};
// use boost::shared_ptr
class user_of_abstract
{
private:
boost::shared_ptr<abstract> m_abstract;
public:
// Pass a pointer to an "abstract" object. The caller takes care of the memory resource.
user_of_abstract_base(boost::shared_ptr<abstract> a) : m_abstract(a) { }
// use the stored member to call fst_func.
int use_fst_func() {
return this->m_abstract->fst_func();
}
// use the stored member to call sec_func.
void use_sec_func(int x) {
this->m_abstract->sec_func(x);
}
};
// pass a pointer of an "abstract" object wherever needed.
struct user_of_abstract
{
// use the passed pointer to an "abstract" object to call fst_func.
int use_fst_func(abstract* a) {
return a->fst_func();
}
// use the passed pointer to an "abstract" object to call sec_func.
void use_sec_func(abstract* a, int x) {
a->sec_func(x);
}
};
It's important to note that parameter "x" from sec_func() needs to be a value returned by fst_func() on the same "abstract" instance.
EDIT:
Added another approach using boost::shared_ptr which should take the most advantages.
I would say that passing the abstract object into the constructor of your user is the proper approach as the methods of the user depend being called on the same abstract object. I would even go further and make the x parameter an internal state of your user as you have said it's important that this value is the one returned from a call from the first function.
Update: If you are worried about the lifetimes then you could make use of the various smart pointer options available in for example boost. Those should cover most usage scenarios.
Since you say the second function should use the output of the first. I guess first approach will decrease chance of mistakes. You can even modify it to the following:
int use_fst_func() {
return x=this->m_abstract->fst_func();
}
void use_sec_func() {
this->m_abstract->sec_func(x);
}
protected:
int x;
You're putting yourself in a sea of maintenance trouble.
In your first example...
there's really no need for the template constructor. It's speced as
// Parse any type, which needs to be derived from "abstract" and create a copy.
The user can already do that by creating the instance himself and pass it to the first constructor.
Also, with this:
// Free memory in destructor.
You explicitly say that you have no idea how this class should be used. As your first example is written, you need to decide: use an instance created from the outside or use an instance created on the inside. It's confusing to see an interface with one ctor taking a pointer and another ctor taking a reference, both essentially to the same type.
In my eyes, the only acceptable way of using an instance created from the outside that will not be memory-managed or an instance created from the inside that will be memory-managed, is when there's a default ctor that can initialize the internal pointer to a sensible value (but that doesn't seem to be the case here, since you want to copy another instance):
template <typename T>
class user_of_abstract
{
bool m_owner_;
abstract* m_abstract;
public:
user_of_abstract_base(abstract* a = NULL)
: m_owner(a == NULL)
, m_abstract(m_owner ? new T(): a)
{
}
~user_of_abstract_base()
{
if (m_owner)
{
delete m_abstract;
}
}
}
Your second example...
is superior to the first, since you don't explicitly mix memory management with memory reference. You let shared_ptr do it implicitly. Very good, that's what it's for.
However, since you have a requirement that use_sec_func must take the output of use_fst_func as input, you stay a long way from the safe shore of the sea of maintenance problems.
For instance, what happens if use_fst_func on an instance throws an exception and use_sec_func is later called on that same instance?
How do you expect that the important information "Always call A before B. And only once. And pass the A result to B." should propagate to users of the class 2 years from now?
Why can't use_sec_func just call use_fst_func?
As for your third example...
can you give 1 single scenario when you'd want to use this instead of just calling the instance functions directly?
I have two structs, in which I'm trying to overwrite a method in the base struct.
The base struct is defined as:
template <class T>
struct compareFunction : public std::binary_function<T,T,bool> {
virtual bool operator() (const T & first, const T & second) {
//This function is always called
return first < second;
}
};
The struct I'm attempting to subclass with is defined as:
template <class Key, class T>
struct valuecomparer : public compareFunction<std::pair<Key,T> > {
std::binary_function<Key, Key,bool> comparer;
bool operator() (const std::pair<Key, T>& x, const std::pair<Key, T> & y) {
//This function is never called
Key tx = x.first;
Key ty = y.first;
if(tx < ty) {
return true;
} else {
return false;
}
}
};
I don't see what I'm doing wrong here, any help would be greatly appreciated.
Ideally, the method in valuecomparer would be called instead of the method in compareFunction.
It is being called basically like this (not necessarily valid syntax,but trying to get idea across):
typedef compareFunction<T> cmpType; //Inside a class definition, T is std::pair<int,double>
valuecomparer<int,double> compareVar;
compareVar.comparer = std:less<int>();
cmpType x = compareVar;
x.compare(std::pair<int,double>(8,20.0),std::pair<int,double>(8,25.0));
Apparently after switching the storage from a pure struct to a struct pointer in the class that is using the base struct (and consequently derived struct), everything works. Thanks for all the help :)
According to the code you've posted, in order to have a overridden derived class' function to be called, you MUST call it from a pointer or reference to the base class type, not an object whose type is of the base class itself. So when you create code like this:
cmpType x = compareVar;
x(std::pair<int,double>(8,20.0),std::pair<int,double>(8,25.0));
that's always going to call the function definition in the base-class since there is no function that can be used for the polymorphic derived function call. The copy-constructor only copies over the v-table entries and associated members from the base-class. So when you call a method on an object of the base-class type, even if you've created that object from a copy of a derived class, you still end up with the base-class method calls. You would have to-do something like this:
cmpType& x = compareVar;
x(std::pair<int,double>(8,20.0),std::pair<int,double>(8,25.0));
Now when the operator() method is called on x, the correct v-table entry is used, that is the overridden version of operator() inside of valuecomparer.
The problem is, from your pseduo-code, you're slicing your comparer:
typedef compareFunction<T> cmpType; //Inside a class definition, T is std::pair<int,double>
valuecomparer<int,double> compareVar;
compareVar.comparer = std:less<int>();
cmpType x = compareVar; // *** SLICED HERE ****
x.compare(std::pair<int,double>(8,20.0),std::pair<int,double>(8,25.0));
The easiest solution, given the context, would be the change the declaration of x to be a reference to cmpType, instead of a full-blown instance.
Edit:
Looking closer, the above will not work, at all (you said it was psuedo), but given the intent, looks like you've meant:
valuecomparer<int,double> compareVar;
compareVar.comparer = std:less<int>();
compareFunction<pair<int, double> > x = compareVar; // *** SLICED HERE ****
x.compare(std::pair<int,double>(8,20.0),std::pair<int,double>(8,25.0));
If you're using your valuecomparer for a std::map, then you're missing the fact that an item in the map is defined as std::pair<const Key, Val>. See the const part? :) Add that to your std::pair<>s. If that isn't the problem, report back where and how you actually use those functors.