Изменение переменных класса во время выполнения? - PullRequest
0 голосов
/ 16 октября 2011

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

int roll_no

и

int reg_no

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

1 Ответ

1 голос
/ 17 октября 2011

Основываясь на слове "Структура" и объявлениях переменных, я собираюсь предположить, что этот вопрос о некоторой разновидности языка 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 объекту * только 1008 * , а не весь класс.Я не уверен, как вы поступите так со всем классом.

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

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

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

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

Атрибуты класса (и методы) 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"));

Обратите внимание, что я не объявлял att static выше, поэтому в этом случае каждый экземпляр класса 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, но это довольно сложно;см. документацию по отражению для получения дополнительной информации.

Удачи!

...