I have the following classes:
EuropeanOption.h
#pragma once
class OptionPricer;
class EuropeanOption
{
protected:
double dividend;
double strike;
double vol;
double maturity;
double spot;
public:
EuropeanOption(void);
virtual ~EuropeanOption(void);
virtual double price(double rate, const OptionPricer& optionPricer) const = 0;
virtual short getSign() const =0;
double getDividend() const;
double getStrike() const;
double getVol () const;
double getMaturity() const;
double getSpot() const;
void setDividend(double dividend_);
void setStrike(double strike_);
void setVol(double vol_);
void setMaturity(double maturity_);
void setSpot(double spot_);
};
EuropeanOption.cpp
#include "OptionPricer.h"
#include "EuropeanOption.h"
EuropeanOption::EuropeanOption(void)
{
}
EuropeanOption::~EuropeanOption(void)
{
}
double EuropeanOption::getDividend() const
{
return dividend;
}
double EuropeanOption::getMaturity() const
{
return maturity;
}
double EuropeanOption::getStrike() const
{
return strike;
}
double EuropeanOption::getSpot() const
{
return spot;
}
double EuropeanOption::getVol() const
{
return vol;
}
void EuropeanOption::setDividend(double dividend_)
{
dividend = dividend_;
}
void EuropeanOption::setMaturity(double maturity_)
{
maturity = maturity_;
}
void EuropeanOption::setSpot(double spot_)
{
spot = spot_;
}
void EuropeanOption::setVol(double vol_)
{
vol = vol_;
}
void EuropeanOption::setStrike(double strike_)
{
strike = strike_;
}
EuropeanCall.h
#pragma once
#include "EuropeanOption.h"
class EuropeanCall :
public EuropeanOption
{
public:
EuropeanCall(void);
EuropeanCall(double spot_, double strike_, double maturity_, double vol_, double dividend_ = 0);
~EuropeanCall(void);
short getSign() const;
double price(const OptionPricer& optionPricer, double rate) const;
}
;
EuropeanCall.cpp
#include "EuropeanCall.h"
#include "OptionPricer.h"
#include <cstdlib>
EuropeanCall::EuropeanCall(void)
{
}
EuropeanCall::EuropeanCall(double spot_, double strike_, double maturity_, double vol_, double dividend_)
{
spot = spot_;
strike = strike_;
maturity = maturity_;
vol = vol_;
dividend = dividend_;
}
EuropeanCall::~EuropeanCall(void)
{
}
short EuropeanCall::getSign() const
{
return 1;
}
double EuropeanCall::price(const OptionPricer& optionPricer, double rate) const
{
return optionPricer.computePrice(*this, rate);
}
OptionPricer.h
#pragma once
#include "EuropeanOption.h"
class OptionPricer
{
public:
OptionPricer(void);
virtual double computePrice(const EuropeanOption& option, double rate) const =0;
virtual ~OptionPricer(void);
};
OptionPricer.cpp
#include "OptionPricer.h"
OptionPricer::OptionPricer(void)
{
}
OptionPricer::~OptionPricer(void)
{
}
In my main function, when trying to instanciate an EuropeanCall like this:
EuropeanCall myCall(spot,strike,maturity,vol);
I get this error message:
object of abstract class type "EuropeanCall" is not allowed
I don't understand why the compiler considers EuropeanCall as an abstract class. Some help please?
You declared:
virtual double price(double rate, const OptionPricer& optionPricer) const = 0;
in your base class but got the parameters the wrong way round in your derived class:
double price(const OptionPricer& optionPricer, double rate) const;
This is not considered an override.
If some member function vf is declared as virtual in a class Base, and
some class Derived, which is derived, directly or indirectly, from
Base, has a declaration for member function with the same
name
parameter type list (but not the return type)
cv-qualifiers
ref-qualifiers
Then this function in the class Derived is also virtual (whether or
not the keyword virtual is used in its declaration) and overrides
Base::vf (whether or not the word override is used in its
declaration).
Since C++11 you can use the override specifier to ensure that a function is indeed virtual and is overriding a virtual function from the base class.
struct A
{
virtual void foo();
void bar();
};
struct B : A
{
void foo() const override; // Error: B::foo does not override A::foo
// (signature mismatch)
void foo() override; // OK: B::foo overrides A::foo
void bar() override; // Error: A::bar is not virtual
};
The function
virtual double price(double rate, const OptionPricer& optionPricer) const = 0;
Is pure virtual function, thus the classes are abstract. You cannot instantiate on instance of a class with a pure virtual function.
Your attempted override does not match this function signature;
double price(const OptionPricer& optionPricer, double rate) const;
The order of the parameters matter. To catch issues such as this, you can use the override specifier and the compiler will check that the function is overriding.
double price(const OptionPricer& optionPricer, double rate) const override;
// The override above will cause a compiler error.
Related
I am trying to initialize an object of a class inside a member function of another class. The problem is that I need to pass a function pointer to the constructor. I do not know how I can make this. This is the error:
no matching function for call to ‘inheritance01::inheritance01(double (inheritance02::*&)(double))’
inheritance01 LT (func);
The code below shows the problem.
class Base01 {
public:
Base01(double (*)(double));
virtual double calc(double) = 0;
double (*ptr_fd() const)(double) { return ptr_fd_; }
private:
double (*ptr_fd_)(double);
};
Base01::Base01(double (*f)(double))
: ptr_fd_(f)
{
}
//----------------------------------------------------
class inheritance01 : public Base01 {
public:
inheritance01(double (*ptr_f)(double));
virtual double calc(double);
};
inheritance01::inheritance01(double (*pf)(double))
: Base01(pf)
{
}
double inheritance01::calc(double t) { return 2.0 * t; }
//###################################################
class Base02 {
public:
Base02(double);
virtual double solution(double, double) = 0;
double a() { return a_; };
private:
const double a_;
};
Base02::Base02(double aa)
: a_(aa)
{
}
//------------------------------------------------------
class inheritance02 : public Base02 {
public:
inheritance02(double, double);
virtual double solution(double, double);
//static double sol_aux (double);
private:
double sol_aux(double);
const double b;
//double (inheritance02::*fptrsol_aux)(double u) = &inheritance02::sol_aux;
typedef double (inheritance02::*fptr)(double u);
fptr func;
};
inheritance02::inheritance02(double aa, double bb)
: Base02(aa)
, b(bb)
{
//func = double (*sol_aux)(double);
//func = &inheritance02::sol_aux;
}
//--------------------------------------------------
double inheritance02::sol_aux(double u)
{
return (a() + b) / u;
}
//--------------------------------------------------
double inheritance02::solution(double x, double t)
{
//inheritance01 LT (&func);
//inheritance01 LT (this->func);
//inheritance01 LT (&fptrsol_aux);
inheritance01 LT(func); // Here is the problem
return LT.calc(x + t);
}
//########################################################
#include <iostream>
int main()
{
inheritance02 obj(1.0, 1.0);
double value = obj.solution(1.0, 1.0);
std::cout << "value = " << value << std::endl;
return 0;
}
As the comment by #Eljay says, you are creating a typedef for a pointer to member function here:
typedef double (inheritance02::*fptr)(double u);
However, the constructor of inheritance01 takes a regular function pointer as an argument:
inheritance01( double (*ptr_f)(double));
so this line:
inheritance01 LT(func); // Here is the problem
doesn't work because the types don't match up (pointer to member functions are not convertible to function pointers).
The easy fix would be to make func a regular function pointer, like this:
typedef double (*fptr)(double u);
and everything should work fine.
Here's a demo.
Although I am not able to declare the 'func_' parameter as const and private (I do not know how to return a std::function) the following code solves my problem:
#include <iostream>
#include <functional>
using namespace std;
class Base01
{
public:
Base01( std::function<double (double)> );
virtual double calc( double ) = 0;
//function<double (double)> func { return func_; }
function<double (double)> func;
private:
//const function<double (double)> func_;
};
Base01::Base01( function<double (double)> f) : func(f) {}
//----------------------------------------------------
class inheritance01:public Base01
{
public:
inheritance01( function<double (double)> );
virtual double calc( double );
};
inheritance01::inheritance01 (function<double (double)> f): Base01(f){}
double inheritance01::calc(double t) { return Base01::func(2.0*t); }
//###################################################
class Base02
{
public:
Base02(double);
virtual double solution(double, double) = 0;
double a(){return a_;};
private:
const double a_;
};
Base02::Base02(double aa): a_(aa) {}
//------------------------------------------------------
class inheritance02 : public Base02
{
public:
inheritance02( double, double );
virtual double solution(double, double);
private:
double sol_aux (double);
const double b;
};
inheritance02::inheritance02 (double aa, double bb)
: Base02(aa), b(bb)
{}
//--------------------------------------------------
double inheritance02::sol_aux(double u) { return (a()+b)/u; }
//--------------------------------------------------
double inheritance02::solution(double x, double y)
{
inheritance01 LT ( bind( &inheritance02::sol_aux, this, placeholders::_1) );
return LT.calc(x+y);
}
//########################################################
int main()
{
inheritance02 obj (1.0,1.0);
double value = obj.solution(1.0,1.0);
std::cout << "value = " << value << std::endl;
return 0;
}
I am currently working on a project that reads postcodes from a .csv file, completes a haversine calculation and stores items in a list based on a returned search radius. The postcode variables are defined via a class and uses an interface to impliment in main.cpp
The method that has thrown this all out of place is the operator < overload to provide alphabetical sorting of the postcodes (to be used to sort the list in main.cpp)
Postcode class;
#ifndef POSTCODE_H_
#define POSTCODE_H_
#include <stdexcept> // std::out_of_range
#include "IPostCode.h"
#include <string>
class PostCode : public IPostCode {
private:
int Id;
std::string Postcode;
std::string firstTwoChars;
double Lattitude;
double Longitude;
double distanceFromCentre;
public:
PostCode();
int getId() override;
std::string getPostcode() override;
std::string getFirstTwoChars() override;
double getLattitude() override;
double getLongitude() override;
double getdistanceFromCentre() override;
bool operator<(const PostCode& right) const override;
void setId(std::string newId) override;
void setPostcode(std::string newPostcode) override;
void setLattitude(std::string newLattitude) override;
void setLongitude(std::string newLongitude) override;
void setdistanceFromCentre(double newdistanceFromCentre) override;
void clearPostCode() override;
};
PostCode::PostCode() {
this->Id = 0;
this->Postcode = "";
this->Lattitude = 0.0f;
this->Longitude = 0.0f;
}
int PostCode::getId()
{
return this->Id;
}
std::string PostCode::getPostcode()
{
return this->Postcode;
}
std::string PostCode::getFirstTwoChars()
{
firstTwoChars = Postcode.substr(0, 2);
return this->firstTwoChars;
}
double PostCode::getLattitude()
{
return this->Lattitude;
}
double PostCode::getLongitude()
{
return this->Longitude;
}
double PostCode::getdistanceFromCentre()
{
return this->distanceFromCentre;
}
void PostCode::setId(std::string newId)
{
this->Id = std::stoi(newId);
}
void PostCode::setPostcode(std::string newPostcode)
{
this->Postcode = newPostcode;
}
void PostCode::setLattitude(std::string newLattitude)
{
this->Lattitude = std::stod(newLattitude);
}
void PostCode::setLongitude(std::string newLongitude)
{
this->Longitude = std::stod(newLongitude);
}
void PostCode::setdistanceFromCentre(double newdistanceFromCentre)
{
this->distanceFromCentre = newdistanceFromCentre;
}
void PostCode::clearPostCode() {
this->Id = 0;
this->Postcode = "";
this->Lattitude = 0.0f;
this->Longitude = 0.0f;
}
bool PostCode::operator<(const PostCode& right) const
{
return (Postcode.compare(right.Postcode) < 0);
}
#endif
Interface code;
#ifndef IPOSTCODE_H_
#define IPOSTCODE_H_
#include <string>
class IPostCode {
public:
virtual int getId() = 0;
virtual std::string getPostcode() = 0;
virtual double getLattitude() = 0;
virtual double getLongitude() = 0;
virtual double getdistanceFromCentre() = 0;
virtual std::string getFirstTwoChars() = 0;
virtual bool operator<(const PostCode& right) const = 0;
virtual void setId(std::string newId) = 0;
virtual void setPostcode(std::string newPostcode) = 0;
virtual void setLattitude(std::string newLattitude) = 0;
virtual void setLongitude(std::string newLongitude) = 0;
virtual void setdistanceFromCentre(double newdistanceFromCentre) = 0;
virtual void clearPostCode() = 0;
};
#endif
Errors.
1. Error C2259 'PostCode': cannot instantiate abstract class (This error is for the main.cpp declaration of a PostCode)
2. Error C3668 'PostCode::operator <': method with override specifier 'override' did not override any base class methods (Error within the postcode class)
3. Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int
4. Error C2143 syntax error: missing ',' before '&' (3 + 4 = Errors within the interface)
I've read that the interface errors are due to type identifiers and i should declare them as static but this presents more error's. I am under the assumption that all methods within the interface are to be overridden as they declared pure virtual methods. (i.e = 0;). This isn't a void method because it returns values when implimented.
This does not resolve all the compiler warnings and errors; only the operator<.
Remove the operator< declaration from class IPostCode:
class IPostCode
{
public:
//--------------------------------------------------------
// Remove the function below
//--------------------------------------------------------
virtual bool operator<(const PostCode& right) const = 0;
};
Remove the override keyword from the PostCode class:
class PostCode : public IPostCode
{
public:
//---------------------------------------------------
// Remove "override" from the declaration below.
//---------------------------------------------------
bool operator<(const PostCode& right) const override;
};
You really don't want to override comparison operators or implement comparison functions in base classes. When you have a pointer of the base class type, you don't know what kind of child class it really points to. You could be comparing two different child classes.
The addBudget function in AuxiliaryOffice class is a friend function of the budget class. But the compiler is giving me error, that it cannot access the private members of the Budget class.
class Budget;
class AuxiliaryOffice
{
private:
double auxBudget;
public:
AuxiliaryOffice()
{
auxBudget = 0;
}
double getDivisionBudget()
{
return auxBudget;
}
void addBudget(double a, Budget &ref)
{
ref.corpBudget += a;
auxBudget += a;
}
};
class Budget
{
private:
static double corpBudget;
double divisionBudget;
friend void AuxiliaryOffice::addBudget(double, Budget&);
public:
Budget()
{
divisionBudget = 0;
}
void addBudget(double a)
{
corpBudget += a;
divisionBudget += a;
}
double getDivisionBudget() const
{
return divisionBudget;
}
double getCorpBudget() const
{
return corpBudget;
}
};
double Budget::corpBudget = 0;
The error you get is stopping your code from compile before friendship is even an issue.
You declared Budget as an incomplete type:
class Budget;
And then wrote code that calls functions on it, before the class is defined. That is not allowed. You have to declare functions that use it, but NOT define it until after the class is defined.
That's why (one of the reasons why) we put class declarations in headers, and implementations in .cpp files. It also reduces coupling between files, and can help with build speeds.
Here's a compacted version of your code that compiles, with most of the unessential lines removed (as you should aim to do in future questions):
class Budget;
class AuxiliaryOffice {
double auxBudget = 0;
public:
void addBudget(double a, Budget &ref);
};
class Budget {
// Unrelated, but useful to know:
// inline statics can be initialized in the class like this, no
// definition necessary in the .cpp file.
inline static double corpBudget = 0;
friend void AuxiliaryOffice::addBudget(double, Budget&);
};
// if in .cpp, remove "inline", if in header, keep it
inline void AuxiliaryOffice::addBudget(double a, Budget &ref) {
ref.corpBudget += a;
}
see it live: https://godbolt.org/z/JYDZMz
The problem is not about friendship, is about the order of definition. At the point you've defined AuxiliaryOffice::addBudget the definition of Budget is incomplete, hence the member corpBudget isn't defined yet.
Change it to:
class Budget;
class AuxiliaryOffice
{
private:
double auxBudget;
public:
AuxiliaryOffice()
{
auxBudget = 0;
}
double getDivisionBudget()
{
return auxBudget;
}
void addBudget(double a, Budget &ref);
};
class Budget
{
private:
static double corpBudget;
double divisionBudget;
friend void AuxiliaryOffice::addBudget(double, Budget&);
public:
Budget()
{
divisionBudget = 0;
}
void addBudget(double a)
{
corpBudget += a;
divisionBudget += a;
}
double getDivisionBudget() const
{
return divisionBudget;
}
double getCorpBudget() const
{
return corpBudget;
}
};
double Budget::corpBudget = 0;
inline void AuxiliaryOffice::addBudget(double a, Budget &ref)
{
ref.corpBudget += a;
auxBudget += a;
}
That will work.
I'm trying to create a .dll file. I define an class
class Contactmodel
public:
Contactmodel();
virtual ~Contactmodel();
Then, I try to create an instance of this class
virtual Contactmodel *clone() const {return new Contactmodel();}
But when I compile, it causes the error: object of abstract class type is not allowed when create an instance of a abstract class
Could you please show me what I did wrong to create an instance and how to fix it? thank you!
My header file
#pragma once
// contactmodelCohesive.h
#include "contactmodel/src/contactmodelmechanical.h"
#ifdef Cohesive_LIB
# define Cohesive_EXPORT EXPORT_TAG
#elif defined(NO_MODEL_IMPORT)
# define Cohesive_EXPORT
#else
# define Cohesive_EXPORT IMPORT_TAG
#endif
namespace cmodelsxd {
using namespace itasca;
class ContactModelCohesive : public ContactModelMechanical {
public:
Cohesive_EXPORT ContactModelCohesive();
Cohesive_EXPORT virtual ~ContactModelCohesive();
virtual void copy(const ContactModel *c);
virtual void archive(ArchiveStream &);
virtual QString getName() const { return "Cohesive"; }
virtual void setIndex(int i) { index_=i;}
virtual int getIndex() const {return index_;}
enum PropertyKeys {
kwKn=1
, kwKs
, kwFric
, kwForce
, kwMoment
, kwState
, kwRGap
, kwConRad
, kwSig
, kwTau
, kwEmod
, kwKRatio
, kwTenStrength
, kwCoh
, kwPhiF
, kwPhiD
, kwInelasDeform
, kwDamagevar
, kwAlpha
, kwLamda
, kwwsig
, kwwcoh
};
virtual QString getProperties() const {
return " kn"
",ks"
",fric"
",coh_force"
",coh_moment"
",state"
",rgap"
",con_rad"
",sigma"
",tau"
",emod"
",kratio"
",ten_strength"
",cohesion"
",phi_f"
",phi_d"
",in_deform"
",D_var"
",alpha"
",lamda"
",w_sig"
",w_coh";
}
enum FishCallEvents { fActivated=0, fBondBreak };
virtual QString getFishCallEvents() const { return "contact_activated,contact_break"; }
virtual QVariant getProperty(uint i,const IContact *) const;
virtual bool getPropertyGlobal(uint i) const;
virtual bool setProperty(uint i,const QVariant &v,IContact *);
virtual bool getPropertyReadOnly(uint i) const;
enum MethodKeys { kwDeformability=1
, kwcohBond
, kwcohUnbond
};
virtual QString getMethods() const {
return "deformability"
",bond"
",unbond";
}
virtual QString getMethodArguments(uint i) const;
virtual bool setMethod(uint i,const QVector<QVariant> &vl,IContact *con=0); // Base 1 - returns true if timestep contributions need to be updated
virtual uint getMinorVersion() const;
virtual bool validate(ContactModelMechanicalState *state,const double ×tep);
//virtual bool endPropertyUpdated(const QString &name,const IContactMechanical *c);
virtual bool forceDisplacementLaw(ContactModelMechanicalState *state,const double ×tep);
virtual DVect2 getEffectiveTranslationalStiffness() const { DVect2 ret = effectiveTranslationalStiffness_; return ret;}
virtual DAVect getEffectiveRotationalStiffness() const {if (!cohProps_) return DAVect(0.0); return cohProps_->coh_AngStiff_;}
virtual ContactModelCohesive *clone() const { return NEWC(ContactModelCohesive()); }
virtual double getActivityDistance() const {return rgap_;}
virtual bool isOKToDelete() const { return !isBonded(); }
virtual void resetForcesAndMoments() { cohF(DVect(0.0)); cohM(DAVect(0.0));}
virtual bool checkActivity(const double &gap) { return (gap <= rgap_ || isBonded()); }
virtual bool isBonded() const { return cohProps_ ? (cohProps_->coh_state_==3) : false; }
bool hasPBond() const {return cohProps_ ? true:false;}
const double & rgap() const {return rgap_;}
void rgap(const double &d) {rgap_=d;}
int cohState() const {return hasPBond() ? cohProps_->coh_state_: 0;}
void cohState(int i) { if(!hasPBond()) return; cohProps_->coh_state_=i;}
double cohKn() const {return (hasPBond() ? (cohProps_->coh_kn_) : 0.0);}
void cohKn(const double &d) { if(!hasPBond()) return; cohProps_->coh_kn_=d;}
double cohKs() const {return (hasPBond() ? (cohProps_->coh_ks_) : 0.0);}
void cohKs(const double &d) { if(!hasPBond()) return; cohProps_->coh_ks_=d;}
double cohFric() const {return (hasPBond() ? (cohProps_->coh_fric_) : 0.0);}
void cohFric(const double &d) { if(!hasPBond()) return; cohProps_->coh_fric_=d;}
double cohTen() const {return (hasPBond() ? (cohProps_->coh_ten_) : 0.0);}
void cohTen(const double &d) { if(!hasPBond()) return; cohProps_->coh_ten_=d;}
double cohLamda() const {return (hasPBond() ? (cohProps_->coh_lamda_) : 0.0);}
void cohLamda(const double &d) { if(!hasPBond()) return; cohProps_->coh_lamda_=d;}
double cohAlpha() const {return (hasPBond() ? (cohProps_->coh_alpha_) : 0.0);}
void cohAlpha(const double &d) { if(!hasPBond()) return; cohProps_->coh_alpha_=d;}
double cohInelas() const {return (hasPBond() ? (cohProps_->coh_inelas_) : 0.0);}
void cohInelas(const double &d) { if(!hasPBond()) return; cohProps_->coh_inelas_=d;}
double cohDvar() const {return (hasPBond() ? (cohProps_->coh_dvar_) : 0.0);}
void cohDvar(const double &d) { if(!hasPBond()) return; cohProps_->coh_dvar_=d;}
double cohCoh() const {return (hasPBond() ? (cohProps_->coh_coh_) : 0.0);}
void cohCoh(const double &d) { if(!hasPBond()) return; cohProps_->coh_coh_=d;}
double cohPhiD() const {return (hasPBond() ? (cohProps_->coh_phid_) : 0.0);}
void cohPhiD(const double &d) { if(!hasPBond()) return; cohProps_->coh_phid_=d;}
double cohPhiF() const {return (hasPBond() ? (cohProps_->coh_phif_) : 0.0);}
void cohPhiF(const double &d) { if(!hasPBond()) return; cohProps_->coh_phif_=d;}
double cohwsig() const {return (hasPBond() ? (cohProps_->w_sig) : 0.0);}
void cohwsig(const double &d) { if(!hasPBond()) return; cohProps_->w_sig=d;}
double cohwcoh() const {return (hasPBond() ? (cohProps_->w_coh) : 0.0);}
void cohwcoh(const double &d) { if(!hasPBond()) return; cohProps_->w_coh=d;}
DVect cohF() const {return hasPBond() ? cohProps_->coh_F_: DVect(0.0);}
void cohF(const DVect &f) { if(!hasPBond()) return; cohProps_->coh_F_=f;}
DAVect cohM() const {return hasPBond() ? cohProps_->coh_M_: DAVect(0.0);}
void cohM(const DAVect &m) { if(!hasPBond()) return; cohProps_->coh_M_=m;}
DVect2 cohTransStiff() const {return hasPBond() ? cohProps_->coh_TransStiff_: DVect2(0.0);}
void cohTransStiff(const DVect2 &f) { if(!hasPBond()) return; cohProps_->coh_TransStiff_=f;}
DAVect cohAngStiff() const {return hasPBond() ? cohProps_->coh_AngStiff_: DAVect(0.0);}
void cohAngStiff(const DAVect &m) { if(!hasPBond()) return; cohProps_->coh_AngStiff_=m;}
const DVect2 & effectiveTranslationalStiffness() const {return effectiveTranslationalStiffness_;}
void effectiveTranslationalStiffness(const DVect2 &v ) {effectiveTranslationalStiffness_=v;}
private:
static int index_;
struct cohProps {
cohProps() : coh_kn_(0.0), coh_ks_(0.0), coh_fric_(0.0), coh_state_(0), coh_ten_(0.0), coh_coh_(0.0),
coh_alpha_(1.0), coh_lamda_(0.0), coh_phid_(0.0), coh_phif_(0.0), coh_dvar_(0.0), coh_inelas_(0.0),
coh_F_(DVect(0.0)), coh_M_(DAVect(0.0)), coh_TransStiff_(0.0), coh_AngStiff_(0.0) {}
// parallel bond
int coh_state_; // Contact mode - 0 (NBNF), 1 (NBFT), 2 (NBFS), 3 (B)
double coh_kn_; // normal stiffness
double coh_ks_; // shear stiffness
double kn0;
double ks0;
double coh_fric_; // Moment contribution factor
double coh_ten_; // normal strength
double coh_coh_; // friction angle
double ten0;
double coh0;
double coh_inelas_; // friction angle
double coh_alpha_; // soften normal stiffness
double coh_lamda_; // soften normal stiffness
double coh_phid_; // soften normal stiffness
double phid0;
double coh_phif_; // soften normal stiffness
double coh_dvar_; // soften normal stiffness
DVect coh_F_; // Force in parallel bond
DAVect coh_M_; // moment in parallel bond
double mn;
double ms;
double w_sig;
double w_coh;
DVect2 coh_TransStiff_; // (Normal,Shear) Translational stiffness of the parallel bond
DAVect coh_AngStiff_; // (Normal,Shear) Rotational stiffness of the parallel bond
};
void updateEffectiveStiffness(ContactModelMechanicalState *state);
DVect3 cohData(const IContactMechanical *con) const; // Bond area and inertia
DVect2 cohSMax(const IContactMechanical *con) const; // Maximum stress (tensile,shear) at bond periphery
double cohShearStrength(const double &cohArea) const; // Bond shear strength
double rgap_; // reference gap for the linear part
cohProps * cohProps_; // The parallel bond properties
DVect2 effectiveTranslationalStiffness_;
}; //ContactModelCohesive
} // cmodelsxd
The reason for having abstract base classes is to provide an interface that concrete classes must implement. You are not supposed to create instances of the abstract base class.
Make clone() a pure virtual function and do not implement it in the base class. Implement it only in the concrete classes.
virtual Contactmodel *clone() const = 0;
You cannot create an instance of Contactmodel if Contactmodel is an abstract class (i.e. contains a pure virtual function). The clone is usually defined as a pure virtual function in a base class, the overloaded in the derived, like
struct IClonable
{
virtual IClonable* clone() const = 0;
virtual ~IClonable() = default;
};
class Foo: public IClonable
{
public:
Foo* clone() const override
{
return new Foo{*this};
}
};
int main()
{
Foo* foo = new Foo;
Foo* clone = foo->clone();
delete clone;
delete foo;
}
or, with smart pointers
#include <memory>
struct IClonable
{
virtual std::unique_ptr<IClonable> clone() const = 0;
virtual ~IClonable() = default;
};
class Foo: public IClonable
{
public:
std::unique_ptr<IClonable> clone() const override
{
return std::make_unique<Foo>(*this);
}
};
int main()
{
std::unique_ptr<IClonable> up_foo{new Foo};
std::unique_ptr<IClonable> up_clone = up_foo->clone();
}
I am new at C++, and have some problems with it. I would like to create an abstract class, and two more abstract classes that inherit from that class. Finally, those two classes are used to be implemented by concrete classes. Here are my header and source files:
/*
* Cylinder.h
*/
#ifndef CYLINDER_H_
#define CYLINDER_H_
class Shape{
public:
virtual ~Shape();
virtual const double area()=0;
virtual const void printDetails();
};
class Shape2D: virtual public Shape{
public:
virtual const double scope()=0;
};
class Shape3D: virtual public Shape{
public:
virtual const double volume()=0;
};
class Rectangle: public Shape2D{
private:
double a;
double H;
public:
Rectangle();
Rectangle(double a, double H);
Rectangle(Rectangle &r);
double getA() const;
double getH() const;
void setA(double a);
void setH(double H);
};
class Circle: public Shape2D{
private:
double r;
public:
Circle();
Circle(double r);
Circle(Circle &c);
double getR() const;
void setR(double r);
};
class Cylinder: public Shape3D{
private:
Circle base;
Rectangle wrapper;
public:
Cylinder();
Cylinder(Rectangle &r, Circle &c);
Cylinder(double a, double H, double r);
Cylinder(Cylinder &c);
double getHeight() const;
double getBaseRadius() const;
double getBaseArea() const;
double getBaseScope() const;
double getWrapperArea() const;
double getWrapperScope() const;
void setHeight(double H);
void setRadius(double r);
Rectangle* getWrapper() const;
Circle* getBase() const;
};
#endif /* CYLINDER_H_ */
/*
* Cylinder.cpp
*/
#include <iostream>
#include "Cylinder.h"
#include <math.h>
using namespace std;
void Shape2D::printDetails() const{
cout<<"\nArea: "<<area();
cout<<"\nScope: "<<scope();
}
void Shape3D::printDetails() const{
cout<<"\nArea: "<<area();
cout<<"\nVolume: "<<volume();
}
Rectangle::Rectangle(){
H=0.0;
a=0.0;
}
Rectangle::Rectangle(double a, double H){
this->H=H;
this->a=a;
}
Rectangle::Rectangle(Rectangle &r){
a=r.a;
H=r.H;
}
Rectangle::~Rectangle(){
cout<<"Rectangle deallocated.";
}
double Rectangle::getA() const{
return a;
}
double Rectangle::getH() const{
return H;
}
void Rectangle::setA(double a){
this->a=a;
}
void Rectangle::setH(double H){
this->H=H;
}
double Rectangle::scope() const{
return 2*a+2*H;
}
double Rectangle::area() const{
return a*H;
}
void Rectangle::printDetails() const{
cout<<"\nDimensions of rectangle: "<<a<<"*"<<H;
Shape::printDetails();
}
Circle::Circle(){
r=0.0;
}
Circle::Circle(double r){
this->r=r;
}
Circle::Circle(Circle &c){
r=c.r;
}
Circle::~Circle(){
cout<<"Circle deallocated.";
}
double Circle::getR() const{
return r;
}
void Circle::setR(double r){
this->r=r;
}
double Circle::scope() const{
return 2*r*M_PI;
}
double Circle::area() const{
return r*r*M_PI;
}
void Circle::printDetails() const{
cout<<"\nRadius of circle: "<<r;
Shape::printDetails();
}
Cylinder::Cylinder(){
wrapper=new Rectangle(0.0,0.0);
base=new Circle(0.0);
}
Cylinder::Cylinder(Rectangle &r, Circle &c){
base=c;
wrapper=r;
}
Cylinder::Cylinder(double a=0.0, double H=0.0, double r=0.0){
wrapper=new Rectangle(a,H);
base=new Circle(r);
}
Cylinder::Cylinder(Cylinder &c){
c.base=new Circle(c.base);
c.wrapper=new Rectangle(c.wrapper);
}
Cylinder::~Cylinder(){
delete base;
delete wrapper;
}
double Cylinder::getHeight() const{
return wrapper.getH();
}
double Cylinder::getBaseRadius() const{
return base.getR();
}
double Cylinder::getBaseArea() const{
return base.area();
}
double Cylinder::getBaseScope() const{
return base.scope();
}
double Cylinder::getWrapperArea() const{
return wrapper.area();
}
double Cylinder::getWrapperScope() const{
return wrapper.scope();
}
void Cylinder::setHeight(double H){
wrapper.setH(H);
}
void Cylinder::setRadius(double r){
base.setR(r);
wrapper.setA(2*base.getR()*M_PI);
}
double Cylinder::volume() const{
return base*wrapper.getH();
}
double Cylinder::area() const{
return 2*base.area+wrapper.area;
}
void Cylinder::printDetails() const{
cout<<"\nRadius of base of Cilynder: "<<base.getR();
cout<<"\nHeight of wrapper: "<<wrapper.getH();
Shape::printDetails();
}
Rectangle* Cylinder::getWrapper() const{
return new Rectangle(wrapper);
}
Circle* Cylinder::getBase() const{
return new Circle(base);
}
My compiler gives me different errors as I try to modify the code to accomplish somehow to have classes Rectangle, Circle and Cylinder as non abstract ones. I am not sure where should I put method definitions (should they be duplicated in inherited classes), and what is their proper form actually. Sorry for long text. I hope someone can help me. Thanks in advance
Sam
You aren't implementing the pure virtual methods. Whenever you have pure virtual methods (virtual void whatever()=0), that makes the class abstract. Abstract classes can not be instantiated. In order to be instantiated, concrete subclasses must implement all the pure virtual methods from ancestor classes.
For example, Rectangle is missing the scope method inherited from Shape2D, and the area method inherited from Shape. That will cause errors along the lines of "can't instantiate Rectangle class because it is abstract." It looks like you have the implementations of those methods lower in the file, but they aren't declared anywhere inside the Rectangle class.