2009-11-02 2 views
4

Can классов имеют несколько конструкторов и/или копировать конструктор в общем-сюсюкать? То есть - для того, чтобы создать класс для нового вектора - «vecr» для представления 3-d векторов действительных чисел, я хотел бы, чтобы определить новый класс, который может быть инициализирован несколькими способами:Несколько Конструкторов в общей шепелявости

(vecr 1.2) ==> #(1.2 1.2 1.2) 

или

(vecr 1.2 1.4 3.2) ==> #(1.2 4.3 2.5) 

или

(vecr) ==> #(0.0 0.0 0.0) 

ответ

7

Я не могу понять, как прокомментировать то, что было сказано выше:

Эта функция работает хорошо, чтобы создать по умолчанию # типа (0,0 0,0 0,0) вектора. Тем не менее, (vecr 1,0) ==> # (1,0 0,0 0,0) вместо предполагаемого # (1,0 1,0 1,0 ). Я полагаю, что путь вокруг этого состоит в том, чтобы проверить, прошли ли все три или только один из необязательных аргументов . - Shamster 6 часов назад

Вы можете сделать это:

(defun vecr (&optional (x 0.0) (y x) (z y)) 
    (vector x y z)) 
+1

Это довольно гладкое решение. Благодаря! – Shamster

3

Там нет "конструкторы" или "копия конструкторы" в Лиспе в том же смысле, как и в C++.

Классов в шепелявости инстанцируются косметика, например, и передаются по ссылке. Это означает, что копирование не происходит.

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

В вашем случае, проще всего иметь такую ​​функцию:

(defun vecr (&optional (x 0.0) (y 0.0) (z 0.0)) 
    (vector x y z)) 
+0

Эта функция работает хорошо, чтобы создать по умолчанию # тип (0,0 0,0 0,0) вектора. Однако (vecr 1.0) ==> # (1.0 0.0 0.0) вместо предполагаемого # (1.0 1.0 1.0). Я полагаю, что путь вокруг этого - проверить, прошли ли все три, или только один из необязательных аргументов. – Shamster

4

Один простой способ заключается в следующем:

(defun vecr (&optional (x 0.0) (y 0.0 y-supplied-p) (z 0.0)) 
    (if y-supplied-p 
     (vector x y z) 
     (vector x x x))) 
3

Смотрите функцию MAKE-ARRAY:

CL-USER 1 > (make-array 3 :initial-element 1.2) 
#(1.2 1.2 1.2) 

CL-USER 2 > (make-array 3 :initial-contents '(1.2 1.4 3.2)) 
#(1.2 1.4 3.2) 

CL-USER 3 > (make-array 3) 
#(NIL NIL NIL) 
+1

Кстати, третий пример также может быть вызван, например, в '# (0 0 0)' - исходный элемент по умолчанию зависит от реализации. – Svante

Смежные вопросы