(the following is an example to simplify the explanation, but it reflects pretty well my real problem)
I have these classes and function, which i can't change or modify:
CannotChangeThis.h
class baseRectangle
{
public:
baseRectangle() : x(0),y(0),w(0),h(0) {}
baseRectangle(int xx, int yy, int ww, int hh) : x(xx),y(yy),w(ww),h(hh) {}
int x,y,w,h; // left, top, width, height
void SetRectangle(int xx, int yy, int ww, int hh)
{
x=xx;y=yy;w=ww;h=hh;
}
int GetRight() {return w-x-1;}
int GetBottom() {return h-y-1;}
[other methods]
}
baseRectangle GetABaseRectangle();
void PassABaseRectangle(baseRectangle br);
I have a derived class that do some computation when you change the base class data:
MyNewClass.h
class DerivedRect : public BaseRectangle
{
private:
DoPreComputation()
{
r=w-x-1;b=h-y-1;
cx=ww/2;cy=hh/2;
}
public:
int r,b,cx,cy; // right, bottom, centerX, centerY
DerivedRect () : r(0),b(0),cx(0),cy(0) {}
void SetRectangle(int xx,yy,ww,hh)
{
BaseRectangle::SetRectangle(int xx,yy,ww,hh);
DoPreComputation();
}
int GetRight() {return r;}
int GetBottom() {return b;}
DerivedRect &operator=(const BaseRectangle &r1 )
{
if (&r1 == this) { return *this; } // prevent assigning to self
BaseRectangle ::operator=(r1);
DoPreComputation();
return *this;
}
}
DerivedRect GetADerivedRect();
void PassADerivedRect(DerivedRect dr);
My problem:
AdvRect rr;
rr = hRect; // this works
AdvRect ar = hRect; // this cause error "conversion from 'BaseRectangle ' to non-scalar type 'DerivedRect' requested"
PassADerivedRect( GetABaseRectangle() ); // Error "no known conversion for.."
PassABaseRectangle( GetADerivedRect() ); // Error "no known conversion for.."
I think i'm missing something very basic about converting or casting between base and derived classes.
I've seen here in stackoverflow what Object slicing is, but since my derived class just do "pre-computation" over the same data, i don't think that should be a problem.
What am i doing wrong?
Instead of a converting assignment operator, make it a conversion constructor.
class DerivedRect : public baseRectangle {
public:
DerivedRect(const baseRectangle &r1 ) : baseRectangle(r1) {
DoPreComputation();
}
// DerivedRect &operator=(const BaseRectangle &r1 ) // no need for this
int r = 0, b = 0, cx = 0, cy = 0; // right, bottom, centerX, centerY
};
Related
Motivated due to the fact, that the avr-g++ places the vtables in RAM, I wrote a replacement using static polymorphy.
Consider the following example:
volatile uint8_t x;
struct IX {
virtual void f() const = 0;
// virtual ~IX() = default; // need delete
};
struct A : public IX {
const uint8_t v = 0;
void f() const override {
x = v;
}
};
struct B : public IX {
const uint8_t v = 1;
void f() const override {
x = v;
}
};
struct C : public IX {
const uint8_t v = 2;
void f() const override {
x = v;
}
};
volatile uint8_t index = 2;
int main() {
A a;
B b;
C c;
const std::array<const IX*, 3> cc{&a, &b, &c};
cc[index]->f();
while(true) {}
}
Here we have some types A, B and C implementing an interface IX and placing pointers in the array cc. Then we call the virtual function f() for a specific instance. (Using this on a small µC like the AVRs, there is a "waste" of RAM, since the vtables are placed in RAM and each object contains a vptr, and a performance penalty due to the indirect call of f().
So I looked for an alternative solution in this case: the simplest way is to use an heterogenous container like std::tuple and write a switch-statement:
const std::tuple<A, B, C> t;
auto f = [](const auto& v) {
v.f();
};
switch (index) {
case 0:
f(std::get<0>(t));
break;
case 1:
f(std::get<1>(t));
break;
case 2:
f(std::get<2>(t));
break;
default:
assert(false);
break;
}
This yields to optimale machine-code but it is an unflexible solution. So I wrote a metafunction to call f() for a specific element of the tuple:
const std::tuple<A, B, C> t;
Meta::visitAt(t, index, [](const auto& v){v.f();});
And the implementation looks like:
namespace Meta {
namespace detail {
template<uint8_t N>
struct visit {
template<typename T, typename F>
static void at(T& tuple, uint8_t index, const F& f) {
if (index == (N - 1)) {
f(std::get<N - 1>(tuple));
}
else {
visit<N - 1>::at(tuple, index, f);
}
}
};
template<>
struct visit<0> {
template<typename T, typename F>
static void at(T&, uint8_t , const F&) {
assert(false);
}
};
template<typename T, typename F, size_t... I>
void all(const T& tuple, const F& f, std::index_sequence<I...>) {
(f(std::get<I>(tuple)), ...);
}
}
template<typename... T, typename F>
void visitAt(const std::tuple<T...>& tuple, uint8_t index, const F& f) {
detail::visit<sizeof...(T)>::at(tuple, index, f);
}
template<typename... T, typename F>
void visitAt(std::tuple<T...>& tuple, uint8_t index, const F& f) {
detail::visit<sizeof...(T)>::at(tuple, index, f);
}
template<typename... T, typename F>
void visit(const std::tuple<T...>& tuple, const F& f) {
detail::all(tuple, f, std::make_index_sequence<sizeof...(T)>{});
}
}
This works very well in my scenarios, yet is obviously limited to static containers (like std::tuple). There is also a for-each-like iteration Meta::visit().
My question is: are there any other drawbacks / limitations with this approach?
Are there any improvements?
I actually have a small question. I want to create an attribute "function" which should be from the class function1, function2 or function3. Is there a way I can do that?
Here is the code:
double Uppersum::evalIntegral(double p_) {
if (functiontype == FUNKTION1){
Function1 function;
}
else if (functiontype == FUNKTION2) {
Function2 function;
}
else if (functiontype == FUNKTION3){
Function3 function;
}
function.setParameterP(p_);
double increment_h = (boundary_b - boundary_a)/num_subintervalls_m;
double sum = 0;
for (int index_i = 0; index_i < num_subintervalls_m -1; index_i++){
double x_1 = index_i * increment_h;
double x_2 = (index_i+1) * increment_h;
double y_1, y_2;
y_1 = function.evalFunctionValue(x_1);
y_2 = function.evalFunctionValue(x_2);
sum += increment_h * std::max(y_1, y_2);
}
}
class Function {
protected:
double parameter_p;
public:
void setParameterP(double p_);
virtual double evalFunctionValue(double x_)=0;
};
class Function1 : public Function {
public:
double evalFunctionValue(double x_);
};
Why not use inheritance, superclass has the virtual functions setParameterP and evalFunctionValue. and in subclasses, override those virtual functions.
here is the test code:
test.cpp
#include <iostream>
typedef enum{
FUNCTION1,
FUNCTION2,
FUNCTION3
}FunctionType;
using namespace std;
class super
{
public:
super(){}
~super(){}
virtual void setParameterP() = 0;
virtual void evalFunctionValue() = 0;
};
class func1:public super
{
public:
func1(){}
virtual void setParameterP(){cout<<"call setParameterP In func1"<<endl;}
virtual void evalFunctionValue(){cout<<"call evalFunctionValue In func1"<<endl;}
};
class func2:public super
{
public:
func2(){}
virtual void setParameterP(){cout<<"call setParameterP In func2"<<endl;}
virtual void evalFunctionValue(){cout<<"call evalFunctionValue In func2"<<endl;}
};
class func3:public super
{
public:
func3(){}
virtual void setParameterP(){cout<<"call setParameterP In func3"<<endl;}
virtual void evalFunctionValue(){cout<<"call evalFunctionValue In func3"<<endl;}
};
class FuncFactory
{
public:
static super* create(FunctionType var)
{
super* ret = nullptr;
switch (var)
{
case FUNCTION1:
ret = new func1();
break;
case FUNCTION2:
ret = new func2();
break;
case FUNCTION3:
ret = new func3();
break;
default:
cout <<"invalid FunctionType" << endl;
}
return ret;
}
};
int main(int argc, char** argv)
{
super* pFunc = FuncFactory::create(FUNCTION1);
pFunc->setParameterP();
pFunc->evalFunctionValue();
delete pFunc;
pFunc = FuncFactory::create(FUNCTION2);
pFunc->setParameterP();
pFunc->evalFunctionValue();
delete pFunc;
pFunc = FuncFactory::create(FUNCTION3);
pFunc->setParameterP();
pFunc->evalFunctionValue();
delete pFunc;
return 0;
}
here is the process result:
result
I am trying to combine multiple sketches I had, by having them as classes in a single sketch and go through them by pressing keys.
I'm not sure I'm following the right method but I'm basically turning them on and off by using a boolean for each. I have something like:
package combiner;
public class Combiner extends PApplet {
//...
ClassNameOne s1;
ClassNameTwo s2;
//...
ClassNameNine s9;
// AllSketches //
boolean[] sketches;
int totalSketches = 9;
String str_ts = String.valueOf(totalSketches);
char char_ts = str_ts.charAt(0);
public void setup() {
size(1920, 1080);
sketches = new boolean[totalSketches];
for (int i = 0; i < sketches.length; i++) {
sketches[i] = false;
}
s1 = new ClassNameOne(this);
s2 = new ClassNameTwo(this);
//...
s9 = new ClassNameNine(this);
}
public void draw() {
//drawingEachSketchIfItsBoolean==True
if (sketches[0] == true) {
s1.run();
} else if (sketches[1] == true) {
s2.run();
//....
}
}
public void keyPressed() {
if (key >= '1' && key <= char_ts) {
String str_key = Character.toString(key);
int KEY = Integer.parseInt(str_key);
for (int i = 0; i < sketches.length; i++) {
sketches[i] = false;
}
sketches[KEY - 1] = true;
//initializingEachClassIfKeyPressed
if (KEY == 0) {
s1.init();
} else if (KEY == 1) {
s2.init();
}
//....
}
}
As you can see each Class has an .init and a .run method (used to be my setup + draw).
I was wandering if somehow I can loop to .init or .run them without having to write it once for each, something like:
for(int i=0;i<sketches.length;i++){
if(sketches[i]==true){
String str = String.valueOf(i+1);
str="s"+str; //str becomes the Object's name
??? str.run(); ???
}
}
The cleanest solution would be to create an interface Sketch, which must be implemented in your sketch classes then:
Sketch[] sketches;
int activeSketch = 0;
void setup(){
sketches = new Sketch[2];
sketches[0] = new SketchRed();
sketches[1] = new SketchGreen();
sketches[activeSketch].init();
}
void draw(){
sketches[activeSketch].draw();
}
interface Sketch{
void init();
void draw();
}
class SketchRed implements Sketch{
void init(){}
void draw(){
fill(255, 0, 0);
ellipse(width/2, height/2, 30, 30);
}
}
class SketchGreen implements Sketch{
void init(){}
void draw(){
fill(0, 255, 0);
ellipse(width/2, height/2, 30, 30);
}
}
void keyPressed(){
activeSketch++;
if(activeSketch >= sketches.length){
activeSketch = 0;
}
sketches[activeSketch].init();
}
I am not sure if the whole idea of representing different sketches as classes in a new sketch is really that good, but in any case there seems to be a possibilty in Java for obtaining a class from a String! Look for Class.forName() as described here: http://docs.oracle.com/javase/tutorial/reflect/class/classNew.htm
Keep in mind that you will obtain a class from this and not an instance yet!
I am coding a Fibonacci sequence in Eclipse and this is my code-
public class FibonacciAlgorithm {
private int a = 0;
private int b = 1;
public FibonacciAlgorithm() {
}
public int increment() {
int temp = b;
b = a + b;
a = temp;
return value;
}
public int getValue() {
return b;
}
}
It is showing an error in the return value; line saying value cannot be resolved to a variable. I don't see any other errors.
Where is value defined? You return something that was not defined anywhere.
You don't have a "value" defined, this is your error. I don't remember the thing exactly, but I think you don't need a and b, I found this in my code archive, hope it helps.
public class Fibonacci
{
public static long fibo(int n)
{
if (n <= 1) return n;
else return fibo(n - 1) + fibo(n - 2);
}
public static void main() {
int count = 5; // change accordingly, bind to input etc.
int N = Integer.parseInt(count);
for (int i = 1; i <= N; i++)
System.out.println(i + ": " + fibo(i));
}
}
In case you want to stay with your own code, try returning "b" as value.
Your method is returning an int variable so you would have to define and return value as an int
I am not sure what you trying to do.
If you have "getValue" method I think "increment" method should be void.
When you want current Fibonacci value use "getValue" method.
public class FibonacciAlgorithm {
private int a = 0;
private int b = 1;
public FibonacciAlgorithm() {
}
public void increment() {
int temp = b;
b = a + b;
a = temp;
}
public int getValue() {
return b;
}
I'm trying to code some stuff for a game but I keep getting error messages on 8 lines that keep saying "Expected '=', ',', ';', 'asm' or 'attribute' before "insert what it's talking about here""
Its annoying and I can't figure out why. Here is the code:
class Vec2 **"error here before Vec2"**
{
public:
float X, Y;
Vec2() {}
Vec2(const float &x, const float &y) :
X(x),
Y(y)
{
};
float &operator[] (const int &index)
{
switch (index)
{
case 0:
return X;
case 1:
return Y;
}
throw Exceptions::IndexOutOfRange();
};
float *operator & ()
{
return &X;
};
};
template<> class TypeInfo<Vec2> : public TypeInfo_Atomic<Vec2> {}; **"error here before <"**
class Vec3 **"error here before Vec3"**
{
public:
float X, Y, Z;
Vec3() {}
Vec3(const float &x, const float &y, const float &z) :
X(x),
Y(y),
Z(z)
{
};
float &operator[] (const int &index)
{
switch (index)
{
case 0:
return X;
case 1:
return Y;
case 2:
return Z;
}
throw Exceptions::IndexOutOfRange();
};
float *operator & ()
{
return &X;
};
};
template<> class TypeInfo<Vec3> : public TypeInfo_Atomic<Vec3> {}; **"error here before <"**
class Vec4 **"error here before Vec4"**
{
public:
float X, Y, Z, W;
Vec4() {}
Vec4(const float &x, const float &y, const float &z, const float &w) :
X(x),
Y(y),
Z(z),
W(w)
{
};
float &operator[] (const int &index)
{
switch (index)
{
case 0:
return X;
case 1:
return Y;
case 2:
return Z;
case 3:
return W;
}
throw Exceptions::IndexOutOfRange();
};
float *operator & ()
{
return &X;
};
};
template<> class TypeInfo<Vec4> : public TypeInfo_Atomic<Vec4> {}; **"error here before <"**
class Color **"error here before Color"**
{
public:
byte R, G, B, A;
Color() {}
Color(byte r, byte g, byte b, byte a) :
R(r),
G(g),
B(b),
A(a)
{
};
byte *operator & ()
{
return &R;
};
static const Color Red,
Green,
Blue,
Yellow,
White,
Black;
};
template<> class TypeInfo<Color> : public TypeInfo_Atomic<Color> {}; **"flag here before <"**
there are 8 errors total. Help would be hugely appreciated!
If you're putting objective-c and c++ code into the same file, you need to use a .mm file extension.
http://developer.apple.com/library/ios/#referencelibrary/GettingStarted/Learning_Objective-C_A_Primer/_index.html
It doesn't think your module is C++. What suffix did you give the file?