一千萬個為什麽

搜索

在運行時更改類變量?

讓我先想一想我想做什麽:我有一個名為 student 的結構或類,其中包含類似的變量

int roll_no

int reg_no

如果用戶希望在運行時添加一個新的變量,如 char name ,該如何完成?

最佳答案

基於單詞“結構”和變量聲明,我猜這個問題是關於C的某些風格。完全這樣做取決於語言,但作為一般規則,如果編譯語言(例如C/C ++,Java的),這是不可能的。如果語言被解釋(例如蟒蛇),這可能是可能的,如下所示:

class MyObj:
  message = "Hi there"

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

在這裏,我們將 name 屬性添加到 a 對象,而不是整個類。我不確定你是怎麽為整個班級做的。

但實際上,你的問題的答案是“不要”。您應該考慮您的程序和您正在使用的對象,以了解您將要和不需要的字段。如果您希望在程序中的某個位置有一個名稱字段,請將其放在類聲明中。如果您不希望它具有對象創建的值,請使用合理的默認值,如 null

編輯

根據您的意見,有幾種方法可以解決這個問題。我仍然不完全清楚你想要什麽,但我認為其中一個案例應該涵蓋它。在我所知的語言中,蟒蛇在運行時是最靈活的:

蟒蛇

In 蟒蛇, a class is just another kind of object. Class variables (check out this question too) belong to the class itself, and are inherited by any instances you create:

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'"

One drawback to using 蟒蛇 is that it can be kinda slow. If you want to use a compiled language it will be slightly more complicated, and it will be harder to get the same functionality that I mentioned above. However, I think it's doable. Here's how I would do it in Java的. The implementation in C/C++ will be somewhat different.

Java的

Java的's class attributes (and methods) are called (and declared) static:

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

static variables are normally accessed through the class name, as in 蟒蛇. You can get at them through an instance, but I believe that generates a warning:

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

You can't add attributes to a Java的 object at runtime:

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

However, you can have a HashMap attribute, static or not, which you can add entries to at runtime that act like attributes. (This is exactly what 蟒蛇 does, behind the scenes.) For example:

class MyObj {
  private HashMap att = new HashMap();

  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 classAtt = new HashMap();
  private HashMap instAtt = new HashMap();

  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);
    }
  }     
}

There are a few details I've left out, like handling the case of the HashMaps not having the value you're asking for, but you can figure out what to do there. As one last note, you can do in 蟒蛇 exactly what I did here in Java的 with a dict, and that might be a good idea if the attribute names will be strings. You can add an attribute as a string in 蟒蛇 but it's kind of hard; look at the documentation on reflection for more info.

祝你好運!

轉載註明原文: 在運行時更改類變量?