我有一組引數定義為一組操作的結構(均值、最小值等)
struct Arguments {
double *data;
int num_data;
Arguments(double *data, int num_data) : data(data), num_data(num_data) {}
};
struct MeanOperationArguments: Arguments {
MeanOperationArguments(double *data, int num_data) : Arguments(data, num_data) {}
};
struct MinmaxOperationArguments: Arguments {
bool is_min_op;
MinmaxOperationArguments(double *data, int num_data, bool is_min_op) : is_min_op(is_min_op), Arguments(data, num_data) {}
};
我需要定義一個操作類如下:
class Operation {
public:
virtual void execute() = 0;
}
class MeanOperation: public Operation {}
// an operation that can be told to display either the minimum or the maximum.
class MinmaxOperation: public Operation {}
另外,我有一個操作工廠,它根據操作型別回傳特定的操作物件實體:
class OperationFactory {
public:
Operation *get(OP_TYPE t, Arguments *args) {
switch(t) {
case MEAN:
return new MeanOperation(args);
case MINMAX:
return args->is_min_op ? // ERROR: Because struct downcasts to `Arguments`
new MinOperation(args):
new MaxOperation(args);
}
}
};
我需要能夠基于引數結構的型別運行我的操作,如下所示:
int main() {
double data[] = { 1, 2, 3, 4 };
int num_data = 4;
OperationFactory operations;
Arguments *mean_args = new MeanOperationArguments(data, num_data);
Operation *mean_op = operations.get(MEAN, mean_args);
mean_op->execute();
Arguments *min_args = new MinmaxOperationArguments(data, num_data, true);
Operation *min_op = operations.get(MINMAX, min_args);
min_op->execute();
return 0;
}
如何根據用例使用 require 引數初始化我的操作?
uj5u.com熱心網友回復:
如果你在基類中放置一個虛方法,最好是解構式,你可以dynamic_cast用來將指標轉換為派生類的實體。如果轉換失敗,您將得到答案,如果轉換成功,您可以呼叫它的任何派生類方法。
uj5u.com熱心網友回復:
有很多事情我必須解決。首先,避免結構父/子關系。它增加了不必要的依賴。查看自定義資料結構之類的結構。資料是一天結束時的資料。只有當你解釋它時,它才有意義。脫離該邏輯,您的引數結構可以簡化為一個陣列,其中包含一個無符號整數,該整數表示該陣列的長度(類似于向量,因此也許您可以考慮使用向量而不是結構)。脫離這個邏輯,您可以采用的最佳方法是使用多個具有不同名稱的函式,這些函式接受相同的引數,但根據您希望它執行的操作回傳不同的結果。這就是我所說的:
#include <iostream>
struct DataSet {
public:
double* data;
int size;
DataSet(double* data, unsigned int size) {
this->data = new double[size];
this->size = size;
for (unsigned int i = 0; i < size; i )
this->data[i] = data[i];
}
};
double mean(const DataSet& dataSet) {
double mean = 0;
for (unsigned int i = 0; i < dataSet.size; i )
mean = dataSet.data[i];
mean = mean / dataSet.size;
return mean;
}
double min(const DataSet& dataSet) {
double min = dataSet.data[0];
for (unsigned int i = 1; i < dataSet.size; i )
if (dataSet.data[i] < min)
min = dataSet.data[i];
return min;
}
double max(const DataSet& dataSet) {
double min = dataSet.data[0];
for (unsigned int i = 1; i < dataSet.size; i )
if (dataSet.data[i] > min)
min = dataSet.data[i];
return min;
}
int main() {
double data[5] = { 1, 2, 3, 4, 5 };
unsigned int size = 5;
DataSet dataSet = DataSet(data, size);
double result = 0;
result = mean(dataSet);
std::cout << "Mean: " << result << std::endl;
result = min(dataSet);
std::cout << "Min: " << result << std::endl;
result = max(dataSet);
std::cout << "Max: " << result << std::endl;
}
為方便起見,我將所有內容都包含在一個 .cpp 檔案中。如果你正在嘗試實作一個系統,我建議創建一個列舉類,存盤一個代表用戶想要執行的操作的列舉值,創建一個指向這些函式的 switch 陳述句。
請注意,傳遞指標時要小心,因為你可能會導致記憶體泄漏。如果您在代碼實作中注意到,我正在執行深拷貝,因此將記憶體所有權傳遞給資料集的結構。
編輯以更好地適應系統設計
#include <iostream>
class DataSet {
public:
double* data;
int size;
DataSet() {
data = nullptr;
size = 0;
}
DataSet(double* data, unsigned int size) {
this->data = new double[size];
this->size = size;
for (unsigned int i = 0; i < size; i )
this->data[i] = data[i];
}
~DataSet() {
if (data != nullptr)
delete(data);
}
};
class Operation {
protected:
DataSet dataSet;
public:
Operation(double* data, unsigned int size) : dataSet(data, size) {
}
virtual double execute() = 0;
};
class Mean : public Operation {
public:
Mean(double* data, unsigned int size) : Operation(data, size) {
}
~Mean() {
}
double execute() {
double mean = 0;
for (unsigned int i = 0; i < dataSet.size; i )
mean = dataSet.data[i];
mean = mean / dataSet.size;
return mean;
}
};
class MinMax : public Operation {
public:
bool useMin;
MinMax(double* data, unsigned int size) : useMin(true), Operation(data, size) {
}
~MinMax() {
}
double execute() {
if (useMin) {
double min = dataSet.data[0];
for (unsigned int i = 1; i < dataSet.size; i )
if (dataSet.data[i] < min)
min = dataSet.data[i];
return min;
}
else {
double min = dataSet.data[0];
for (unsigned int i = 1; i < dataSet.size; i )
if (dataSet.data[i] > min)
min = dataSet.data[i];
return min;
}
}
};
int main() {
double data[5] = { 1, 2, 3, 4, 5 };
unsigned int size = 5;
DataSet dataSet = DataSet(data, size);
double result = 0;
Mean mean = Mean(data, size);
std::cout << "Mean: " << mean.execute() << std::endl;
MinMax minMax = MinMax(data, size);
std::cout << "MinMax: " << minMax.execute() << std::endl;
minMax.useMin = false;
std::cout << "MinMax: " << minMax.execute() << std::endl;
}
為了更好地適應您的系統,我制定了一個更好的解決方案。我仍然擺脫了您的結構層次結構,但將層次結構保留在您的類中。MinMax 將根據useMin布林值回傳 min 或 max。你說你在評論中列印它,所以你只需要將它更改為void而不是回傳值,只需列印它。我希望這能為您指明一個更好的方向。
uj5u.com熱心網友回復:
就像是:
case MINMAX:
return dynamic_cast<MinmaxOperationArguments*>(args)->is_min_op ?
new MinOperation(args):
new MaxOperation(args);
}
請注意,應在使用前檢查轉換結果,否則在引數不正確的情況下可能會崩潰。必須啟用 RTTI。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/537135.html
標籤:C 哎呀遗产结构
