Изменение переменных класса во время выполнения?

Позвольте мне дать представление о том, что я хочу сделать: у меня есть структура или класс с именем student, который содержит переменные, такие как

int roll_no

а также

int reg_no

Если пользователь хочет добавить новую переменную, такую ​​как char name во время выполнения, как это можно сделать?

1 ответ

Решение

Основываясь на слове "Структура" и объявлениях переменных, я собираюсь предположить, что этот вопрос о некоторой разновидности языка C. Как именно это сделать, будет зависеть от языка, но, как правило, если язык скомпилирован (например, C/C++, Java), это невозможно. Если язык интерпретируется (например, Python), это может быть вроде как:

class MyObj:
  message = "Hi there"

a = MyObj()  # Creating a new instance variable
a.name = "Bill" # Adding a new attribute

Здесь мы добавили name приписать a только объект, а не весь класс. Я не уверен, как ты справляешься с этим для всего класса.

Но на самом деле ответ на ваш вопрос - "Не надо". Вы должны думать о своей программе и объектах, которые вы используете, достаточно, чтобы знать, какие поля вам нужны и не нужны. Если вы хотите иметь поле имени в какой-то момент в вашей программе, поместите его в объявление класса. Если вы не хотите, чтобы оно имело значение при создании объекта, используйте разумное значение по умолчанию, например null,

редактировать

Основываясь на ваших комментариях, есть несколько способов подойти к этому. Я до сих пор не совсем понимаю, что вы хотите, но я думаю, что один из этих случаев должен охватить это. Из языков, которые я знаю, Python является наиболее гибким во время выполнения:

питон

В Python класс - это просто другой тип объекта. Переменные класса (проверьте этот вопрос тоже) принадлежат самому классу и наследуются любыми созданными вами экземплярами:

class MyObj:
  a = 2            # A class variable
  b = "a string"   # Another one

ObjInstance = MyObj()  # Creating an instance of this class
print ObjInstance.a  # Output: "2"    
ObjInstance.a = 3  # You can access and change the value of class variables *for this instance*    
print MyObj.a, ObjInstance.a  # Outputs "2 3".  We've changed the value of a for the instance

MyObj.c = (3,4)  # You can add a new class variable at runtime    
# Any instance objects inherit the new variable, whether they already exist or not.
print MyObj.c, ObjInstance.c  # Outputs "(3, 4) (3, 4)"

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

ObjInstance.d = "I belong to ObjInstance!"
print ObjInstance.d   # Output: "I belong to ObjInstance!"
print MyObj.d  # Throws "AttributeError: class MyObj has no attribute 'd'"

Недостатком использования Python является то, что он может быть немного медленным. Если вы хотите использовать скомпилированный язык, это будет немного сложнее, и будет сложнее получить ту же функциональность, что я упоминал выше. Тем не менее, я думаю, что это выполнимо. Вот как я бы сделал это на Java. Реализация в C / C++ будет несколько иной.

Джава

Атрибуты класса Java (и методы) вызываются (и объявляются) static:

class MyObj {
  public static int a = 2;
  public static String b = "a string";
}

static Доступ к переменным обычно осуществляется через имя класса, как в Python. Вы можете получить на них через экземпляр, но я считаю, что генерирует предупреждение:

System.out.println(MyObj.a);   //Outputs "2"
MyObj ObjInst = new MyObj();
System.out.println(ObjInst.a);  //Outputs "2" with a warning.  Probably.

Вы не можете добавлять атрибуты к объекту Java во время выполнения:

ObjInst.c = "This will break";  // Throws some exception or other

Тем не менее, вы можете иметь HashMap атрибутов, static или нет, к которому вы можете добавлять записи во время выполнения, которые действуют как атрибуты. (Это именно то, что делает Python, за кулисами.) Например:

class MyObj {
  private HashMap<String, Object> att = new HashMap<String, Object>();

  public void setAttribute(String name, Object value) {
    att.put(name, value);
  }

  public Object getAttribute(String name) {
    return att.get(name);
  }     
}

И тогда вы можете делать такие вещи, как:

ObjInst.setAttribute("name", "Joe");
System.out.println(ObjInst.getAttribute("name"));

Обратите внимание, что я не объявлял attstatic выше, так что в этом случае каждый экземпляр MyObj Класс имеет этот атрибут, но сам класс не имеет. Если бы я объявил это staticу самого класса будет одна копия этого хэша. Если вы хотите стать действительно модным, вы можете объединить два случая:

class MyObj {
  private static HashMap<String, Object> classAtt = new HashMap<String, Object>();
  private HashMap<String, Object> instAtt = new HashMap<String, Object>();

  public static void setClassAttribute(String name, Object value) {
    classAtt.put(name, value);
  }

  public void setInstAttribute(String name, Object value) {
    instAtt.put(name, value);
  }

  public Object getAttribute(String name) {
    // Check if this instance has the attribute first
    if (this.instAtt.containsKey(name) {  
      return instAtt.get(name);
    }
    // Get the class value if not
    else {
      return classAtt.get(name);
    }
  }     
}

Есть несколько деталей, которые я оставил, например, дело со случаем HashMapне имеет значения, которое вы просите, но вы можете выяснить, что делать там. Как последнее замечание, вы можете сделать в Python именно то, что я сделал здесь в Java с dictи это может быть хорошей идеей, если имена атрибутов будут строками. Вы можете добавить атрибут в виде строки в Python, но это довольно сложно; посмотрите на документацию по отражению для получения дополнительной информации.

Удачи!

Другие вопросы по тегам