LINUX.ORG.RU

Подскажите с реализацией кода

 


0

1

На данный момент есть код на уровне идеи. Знаю что он неправильно работает.
Подскажите как реализовать эту идею правильно.

Суть такая - есть несколько потомков от одного класса, у которых может в зависимости от параметра k содержаться массив разной длины с данными.
Параметр k для класса постоянен, массив foo при заданном параметры тоже постоянен.

class A() {
  int k;
  int *foo = new int[k];
  
  switch(k) {
  case 1:
    foo[0] = 1;
  case 2:
    foo[0] = 2;
    foo[1] = 3;
  }
}

class B: public A() {
  k = 1;
}

class C: public A() {
  k = 2;
}

class D: public A() {
  k = 2;
}

void main() {
  B b;
  C c;
  D d;
  return 0;
}

★★★★★

какой-то гибрид скалы и с++.

crowbar
()

От простого (в плане обучения) к сложному (и правильному).

1. В классе массив объявляй через указатель int *array. В конструкторе класса выделяй память и заполняй. В деструкторе освобождай память.

2. Вместо массива используй std::vector.

3. Задавай k как шаблонный аргумент класса.

template<int k>
class X{
int array[k];
};

staseg ★★★★★
()
Ответ на: комментарий от nanoolinux

Дело не в векторе, а в инициализации классов. Ведь потомок при создании должен правильно получить массив с нужными данными.

Zodd ★★★★★
() автор топика
Ответ на: комментарий от staseg

сложному (и правильному)

Задавай k как шаблонный аргумент класса

Излишняя сложность, к тому же приводящая к дополнительным ограничениям

yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt

В конструкторе указывай этот k параметром.

Я раньше так делал, потом показалось слишком неудобным, т.к. надо держать в голове что это за параметр.

Zodd ★★★★★
() автор топика
Ответ на: комментарий от Zodd

потом показалось слишком неудобным, т.к. надо держать в голове что это за параметр.

комментарий к конструктору допиши :)

yoghurt ★★★★★
()
Ответ на: комментарий от anonymous

У меня массивы - это весовые коэффициенты, которые отличаются от степени точности расчета и класса (для каждого класса д.б. своя минимальная точность). Чем их больше, тем «точнее».

Zodd ★★★★★
() автор топика
Ответ на: комментарий от Zodd

Что значит - Напиши по правилам C++?

http://ru.cppreference.com/w/

// Я ведь не программист по образованию

это ничего не меняет. если пишешь на языке - потрудись почитать о том, как на нем писать.

class A {
private:
  const int k;
  int *foo;

public:
  A(int p = 1)
    : k(p)
  {
    foo = new int[k];
  }
  
  ~A() { delete [] foo; }

  void bar() {
    switch(k) {
    case 1:
      foo[0] = 1;
    case 2:
      foo[0] = 2;
      foo[1] = 3;
    }
  }
};

class B: public A {
public:
  B() : A(2) { }
};

class C: public A {
public:
  C() : A(2) { }
};

class D: public A {
public:
  D() : A(3) { }
};

int main() {
  B b;
  C c;
  D d;
  return 0;
}

можно и шаблоном решить, но этого хватит для начала.

dib2 ★★★★★
()
Ответ на: комментарий от false

Это понятно, завозка в том, что массив уже должен быть заполнен и я пытался избежать дублирования заполнения массива.

Zodd ★★★★★
() автор топика
Ответ на: комментарий от yoghurt

ТС говорит, что массив не будет изменяться, в этом смысле ограничений нет. Вообще в реальности такой способ мне пригодился всего пару раз, когда нужно было хранить данные без «мусора», создаваемого вектором. Ну и наверное по производительности оно чуть лучше. Уговорил, меняем 2 и 3 местами :)

staseg ★★★★★
()
Ответ на: комментарий от dib2

Если ты про всякие деструкторы, то я для наглядности кода их убрал.

А вот A(2) интересная идея. Спасибо.

Zodd ★★★★★
() автор топика
Ответ на: комментарий от Zodd

нет, я про class A(), точки с запятыми, конструкторы, и void main(). Не за что

dib2 ★★★★★
()
Ответ на: комментарий от Zodd

А вот A(2) интересная идея. Спасибо.

Тебе про неё уже несколько раз сказали, сославшись на параметр конструктора :)

yoghurt ★★★★★
()
Ответ на: комментарий от Zodd

Классы никто не инициализирует никогда. Инициализируют объекты. Для твоих целей есть список инициализации.

nanoolinux ★★★★
()

А какова предметная область? Наверняка же наследование пытаетесь прикрутить где не надо.

CARS ★★★★
()

Поддерживаю идею с шаблонами. И внесу ещё одно замечание. Тебе надо инициализировать массив по определённому алгоритму, так и заведи соответствующий метод

#include <iostream>
#include <vector>

template<int k>
class T{
public:
    T() {
        initialize(k);
    };
    void initialize(const int n) {
        array = std::vector<int>(n);
        for(int i=0; i<n; ++i)
            array[i]=i;
    }
    std::vector<int> array;
};

int main() {
    T<1> a;
    T<20> b;
    std::cout << "a:";
    for(auto &e: a.array)
        std::cout << ' ' << e;
    std::cout << "\nb:";
    for(auto &e: b.array)
        std::cout << ' ' << e;
    return 0;
}
AlexVR ★★★★★
()
Ответ на: комментарий от CARS

Наверняка же наследование пытаетесь прикрутить где не надо.

+1

Твоя задача может решиться и без всяких наследований и шаблонов, а только за счет вызова конструктора с параметрами.

AlexVR ★★★★★
()
Ответ на: комментарий от AlexVR

И получил по абсолютно одинаковой копии функции initialize для каждого варианта шаблонного аргумента. Выкинь её из класса, пусть принимает вектор как параметр (ну или пару итераторов).

Gvidon ★★★★
()
Ответ на: комментарий от yoghurt

Здесь есть нюанс в потомке не надо указывать этот параметр :)

Zodd ★★★★★
() автор топика
Ответ на: комментарий от CARS

Предметная область - численные методы, метод конечных элементов.

Zodd ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.