Как инициализировать членов константы структур на "куче"

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

#include <stdlib.h>

typedef struct {
  const int x;
  const int y;
} ImmutablePoint;

ImmutablePoint * make_immutable_point(int x, int y)
{
  ImmutablePoint *p = (ImmutablePoint *)malloc(sizeof(ImmutablePoint));
  if (p == NULL) abort();
  // How to initialize members x and y?
  return p;
}

Я должен сделать вывод из этого, что невозможно выделить и инициализировать структуру на "куче", которая содержит участников константы?

38
задан user268344 8 February 2010 в 00:52
поделиться

4 ответа

Примерно так:

ImmutablePoint *make_immutable_point(int x, int y)
{
  ImmutablePoint init = { .x = x, .y = y };
  ImmutablePoint *p = malloc(sizeof *p);

  if (p == NULL) abort();
  memcpy(p, &init, sizeof *p);

  return p;
}

(Обратите внимание, что в отличие от C ++, нет необходимости приведите возвращаемое значение malloc в C, и это часто считается плохим тоном, потому что оно может скрыть другие ошибки).

54
ответ дан 27 November 2019 в 03:37
поделиться

Если вы настаиваете на сохранении константы в структуре, вам придется выполнить приведение типов, чтобы обойти это:

int *cheat_x = (int *)&p->x;
*cheat_x = 3;
2
ответ дан 27 November 2019 в 03:37
поделиться

Как и так:

ImmutablePoint *make_immutable_point(int x, int y)
{
  ImmutablePoint init = { .x = x, .y = y };
  ImmutablePoint *p = malloc(sizeof *p);

  if (p == NULL) abort();
  memcpy(p, &init, sizeof *p);

  return p;
}

(Обратите внимание, что в отличие от C++ нет необходимости приводить возвращаемое значение malloc в C, и оно часто считается плохой формой, поскольку может скрывать другие ошибки).

-121--1226974-

IS-A, HAS-A и т.д. на самом деле не очень OO. Вместо этого принцип замещения Лискова представляет собой ОО.

Дядя Боб проливает свет на историю IS-A у http://www.hanselminutes.com/default.aspx?showID=163

Роберта К. Мартина: Слово «ISA» вкралось в наш словарный запас и по пути, что это одно слово ISA, оно вкралось в наш словарный запас по круговому маршруту и стало очень важным в объектно-ориентированных кругах, но оно не началось так путь. Он прокрался в 80-х через толпу ИИ, которая создала эти замечательные сети знаний, вы можете вспомнить это, всю шумиху об искусственном интеллекте в конце 80-х годов, в начале 90-х, а затем создали эти структуры, которые будут ходить сети знаний эти механизмы вывода, и отношения между образованиями и сетями знаний с такими вещами, как: как, на вкус, как, пахнет как ISA, все эти отношения - отношения, как и, имеет и, когда толпа ИИ потерял финансирование, И все эти финансовые диски, они как бы посмотрели и сказали: "О, есть и другие вещи, это круто. Слушай, там такие отношения, как есть и есть, они очень похожи, мы должны просто переехать. " И они вроде как сделали, и словарный запас изменился. Это интересно, это также немного жаль, потому что наследство не ISA. Наследование, если вы посмотрите на него с очень затемненным глазом, наследование - это объявление методов и переменных в подскопе, и оно не имеет ничего общего с ISA, и понятие ISA может быть очень смешанным. Простой пример, целое число - вещественное число, а вещественное число - комплексное число. Вы могли бы нарисовать, что в вашем UML, это было бы очень просто со всем наследованием там и так далее, но подумайте о попытке составить его. Целое число, мы надеемся, будет 16 или, может быть, 64 бита, но если это будет производным от вещественного числа, вещественное число имеет два целых числа в нем, мантисса и характеристики, экспонента и они используют, они подразумевают двоичные точки внутри них, чтобы сделать эти числа с плавающей точкой. Число с плавающей запятой, вещественное число, происходит из комплекса, но комплекс имеет два вещественных числа в нем, мнимую и действительную часть. Если бы вы думали о написании этого в C++ или на Java, вы бы написали структуру, которая не может быть скомпилирована, потому что она имеет бесконечную мысль. Имеет идеальный смысл в английском языке вообще не имеет смысла в программном обеспечении.

-121--963965-

Если это C, а не C++, я не вижу другого решения, кроме как разрушить систему типов.

ImmutablePoint * make_immutable_point(int x, int y)
{
  ImmutablePoint *p = malloc(sizeof(ImmutablePoint));
  if (p == NULL) abort();

  // this 
  ImmutablePoint temp = {x, y};
  memcpy(p, &temp, sizeof(temp));

  // or this
  *(int*)&p->x = x;
  *(int*)&p->y = y;

  return p;
}
11
ответ дан 27 November 2019 в 03:37
поделиться

Мне нравится подход caf , но это тоже произошло со мной

ImmutablePoint* newImmutablePoint(int x, int y){ 
   struct unconstpoint {
      int x;
      int y;
   } *p = malloc(sizeof(struct unconstpoint));
   if (p) { // guard against malloc failure
      *p.x = x;
      *p.y = y;
   }
   return (ImmutablePoint*)p;
}
1
ответ дан 27 November 2019 в 03:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: