Изменение переменных класса во время выполнения?
Позвольте мне дать представление о том, что я хочу сделать: у меня есть структура или класс с именем 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"));
Обратите внимание, что я не объявлял 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, но это довольно сложно; посмотрите на документацию по отражению для получения дополнительной информации.
Удачи!