how can I assign an inherited method to an object? , can you explain to me what is wrong with my code? I am a newbie, so I would like to know if there is a better way to do it
int main(){
CalculateData data;
data = data.ReadData(data);//does not let me assign data to the method??
}
Rest of the code
#include<string>#include<fstream>#include<iostream>#include<vector>using namespace std;
class File//base class
{
private:
double Size;
public:
vector <double>values;
double GetSize();
void SetSize(double size);
File ReadData(File data);
};
class CalculateData :public File {//inherent from file class
public:
std::vector <double> value;
}
File File::ReadData(File file) {//method of File class
{std::fstream File("Data.txt", std::ios_base::in);
double a;
int counter = 0;
while (File >> a)
{
//printf("%f ", a);
file.values.push_back(a);
counter ;
}
file.SetSize(counter);
cout << "size is " << file.GetSize() << endl;
File.close();
}
return file;
}
CodePudding user response:
Frankly, it is hard to help, because the error is just a consequence of a flawed approach. I'll use an example simpler than yours that has most of the same issues:
#include <iostream>
struct Base {
int value;
Base read(Base b) {
b.value = 42;
return b;
};
};
struct Derived : Base{
int values;
};
int main() {
Derived d;
d = d.read(d);
}
The immediate problem is the compiler error:
<source>: In function 'int main()':
<source>:17:17: error: no match for 'operator=' (operand types are 'Derived' and 'Base')
17 | d = d.read(d);
| ^
<source>:11:8: note: candidate: 'constexpr Derived& Derived::operator=(const Derived&)'
11 | struct Derived : Base{
| ^~~~~~~
<source>:11:8: note: no known conversion for argument 1 from 'Base' to 'const Derived&'
<source>:11:8: note: candidate: 'constexpr Derived& Derived::operator=(Derived&&)'
<source>:11:8: note: no known conversion for argument 1 from 'Base' to 'Derived&&'
d is a Derived and read returns a Base. They are different types, you cannot assign them to each other unless you provide some conversion between them.
However, it does not make sense that read takes a Base as argument (by value) and returns that just to let the caller assign it to the object they called the method on. If the method is intended to modify the current object then it should do so directly:
void read() {
value = 42;
}
There is absolutely no need to pass a Base as argument, which will be copied anyhow, because you pass it by value.
The next thing that is fishy in the code is that Derived has another member which is similar named as the one of Base but unused. Derived already does inherit the value member from Base. It does not need another values member.
Last but not least, initialization of members should take place in the initializer list of the constructor (if not in-class initializers are used). If initialization is complicated a static method can be used. Hence:
struct Base {
int value;
Base() : value( read_input() ) {}
static int read_input() {
return 42;
}
};
struct Derived : Base {};
int main() {
Derived d;
}
This code does the same as the above. As it is not clear what the purpose of Derived is, it can be removed.
