Войти
ПрограммированиеФорумОбщее

Помогите разобраться где я не прав (6 стр)

Страницы: 1 2 3 4 5 6
#75
13:02, 1 ноя 2016

eXmire
> Какое отношение указатели имеют к ссылкам?
Я уже запутался. Ты про какие ссылки вообще говоришь?

Не про &
> Слишком узко мыслишь. Речь не про так называемые "ссылки" языка C++.
Не про *
> Мне снова-таки непонятно, каким местом здесь указатели всплыли, если речь была
> про ссылки?

#76
13:35, 1 ноя 2016

-Eugene-
> Я уже запутался. Ты про какие ссылки вообще говоришь?
Ссылка:
- внешне полностью повторяет value, но любое изменение данных по ссылке отражается на объекте, находившемуся по правую сторону знака "равно" при присваивании/инициализации 
- если ссылка указывает на объект, значит объект обязан существовать. иными словами, время жизни объекта определяется временем жизни всех ссылок на него
Речь про концепт. Конкретная реализация не имеет значения. Ну и само собой, ссылки должны быть переприсваиваемыми, а не константными, как в C++.

#77
13:45, 1 ноя 2016

eXmire

- Скажите, а правда, что Абрамович выиграл в лотерею миллион?
- Правда, только не Абрамович, а Рабинович, не в лотерею, а в карты, не миллион, а сто рублей и не выиграл, а проиграл.

#78
2:21, 2 ноя 2016

говорите, умные указатели, надо везде и всюду использовать?

ага:

#include <glfw3.h>

std::shared_ptr<GLFWwindow> m_window = std::make_shared<GLFWwindow>(glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr));
+ Показать


Ну и сиди, думай о бытии этого мира.....

Бажа в том что в GLFW не дают сам объект. только его объявление:
glfw3.h:

typedef struct GLFWwindow GLFWwindow;

А умному указателю капец как надо оператор копирования
Хотя в данном случае именно тут он и нужен был, потому что GLFWwindow потом по движку расходится в разные направления со всеми вытекающими

Может это решаемо? (нет, так нет, не хочу заморачиваться - все равно еще перепишется)

p.s. да, у меня русская студия и мне глубоко фиолетово. я не фанатик (а если нужно уточнение, ошибки ищу по кодам типа error C2079)

#79
5:28, 2 ноя 2016

war_zes
Скорее всего из-за того, что glfwCreateWindow() выделяет память используя calloc(). std::shared_ptr освобождает память использую delete, а не free(). Это две разные системы распределения памяти их смешивать нельзя.

#80
7:27, 2 ноя 2016

Funtik
Можно добавить glfwDestroyWindow как свой deleter, не сложнее лямбды.
war_zes
Там везде указатели используются, потому особо никто не запаривается с определением структур. С-стиль, что поделать, он всегда плохо уживался с плюсами. Создайте свой класс с обёрткой указателя, перегрузите оператор разыменования и взятия адреса, и будет вам пол-счастья

class Int {
  int * i;
public:
  Int(int j = 0):i(new int(j)){}
  int* pointer(){return i;}
  int& value(){return *i;}
  ~Int(){delete i; i = nullptr;}

};
int& operator*(shared_ptr<Int>& i) {
  return i->value();
}
int* operator&(shared_ptr<Int>& i) {
  return i->pointer();
}

int main() {
  shared_ptr<Int> k(new Int(16));
  *k = 64;
  return *k;
}
#81
2:54, 4 ноя 2016

war_zes
> говорите, умные указатели, надо везде и всюду использовать?
Нет, нужно думать головой.

Если мы видим вот такой код:

typedef struct GLFWwindow GLFWwindow;

Значит имеем дело с интерфейсной частью библиотеки, написанной на Си. И как уже отметили выше, пихать такие вещи в shared_ptr нельзя (хотя это вроде очевидно должно быть Оо).

war_zes
> Бажа в том что в GLFW не дают сам объект. только его объявление
В том месте нет никакого объявления объекта, это нужно лишь для определения своего типа указателя (GLFWwindow *), и следовательно какой-то мало мальской "type safety".

В данном случае мы имеем хендлы. И shared_ptr к ним неприменим, ни с кастомными дэлитерами, ни без. Он чисто логически к ним не применяется.

#82
2:58, 4 ноя 2016

eXmire
> . И shared_ptr к ним неприменим, ни с кастомными дэлитерами, ни без. Он чисто
> логически к ним не применяется
Почему это? Он применим к любой сущности, которую можно создать и удалить, зато нежелательно или невозможно копировать.

#83
5:31, 4 ноя 2016

eXmire
> В данном случае мы имеем хендлы. И shared_ptr к ним неприменим, ни с кастомными
> дэлитерами, ни без. Он чисто логически к ним не применяется.

все там прекрасно применяется.
и технически, и логически.


war_zes
> Может это решаемо

да.

сначала рассмотрим вашу ошибку:

std::shared_ptr<GLFWwindow> m_window = std::make_shared<GLFWwindow>(glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr));

упрощаю запись:

// указатель на построенный объект
GLFWwindow* ptr = glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr); 

std::make_shared<GLFWwindow>(ptr); // <—- WTF???

ваша ошибка в недопонимании принципа работы фабрики смарт-поинтеров.
как работает std::make_shared?

он пинает конструктор объекта, дергая конструктор с указанными аргументами

то есть, вы попытались построить объект неполного типа,
передав в качестве аргумента указатель на другой объект,
который был построен с помощью апи-функции.

как вы видите, кейс вообще не правильный,
вам здесь std::make_shared вообще не нужен.
у вас уже есть апи-функция,
которая умеет строить нужные вам объекты.

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


концептуальный пример:

http://rextester.com/TCZLXN13246

#include <iostream>
#include <memory>

typedef struct GLFWwindow GLFWwindow;
    
struct GLFWmonitor{};

// допустим это наша апи-функция для создания сишных объектов
GLFWwindow* glfwCreateWindow(int width, int height, const char *title, GLFWmonitor *monitor, GLFWwindow *share)
{
    static int hack = 10;
    
    std::cout << "window: " << hack << " was created\n";
    return (GLFWwindow*)&hack;
}

// соотвественно, должна быть функция удаления этих объектов
void glfwDestroyWindow(GLFWwindow *window)
{
    int* hack = (int*)window;
    std::cout << "window: " << *hack << " was destroyed\n";
}


int main()
{
    std::cout << "Hello, world!\n";
    
    // для создания объекта используем специально предназначенное для этого апи
    auto* ptr =  glfwCreateWindow(800, 600, "ololo", nullptr, nullptr);
    
    // далее создаем шаред_птр, указав ресурс, и апи-функцию удаления    
    std::shared_ptr<GLFWwindow> window(ptr, glfwDestroyWindow);
    
}

ну и так, для ознакомления:

смарт-поинтеры - это больше чем просто способ контроля за утечками памяти.
это - мощный паттерн,
позволяющий детально контролировать время жизни и права доступа ресурсов.
(с)

http://www.cyberforum.ru/cpp-beginners/thread1500101.html#post7882976

#84
16:13, 4 ноя 2016

Kartonagnick
> все там прекрасно применяется.
> и технически, и логически.
Про "технически" никто ничего не говорил. Насчет логически:
В документации GLFW четко сказано, что GLFWwindow* - это хендл. А значит, логически, это никакой не "указатель на объект", а некий идентификатор. Хедл в качестве инвалидного значения может иметь NULL, а может и любой другой INVALID_HANDLE.
Это может быть вообще не указатель, а просто индекс.
А теперь ответь мне на такой вопрос: какой смысл приобретает операция разыменовывания в случае shared_ptr<GLFWwindow>?.

#85
20:13, 4 ноя 2016

eXmire
> В документации GLFW четко сказано, что GLFWwindow* - это хендл.
в документации указан прототип:
GLFWwindow* glfwCreateWindow(int width, int height, const char *title, GLFWmonitor *monitor, GLFWwindow *share)
и это все, что нужно знать, что бы работать.

eXmire
> А значит, логически, это никакой не "указатель на объект", а некий
> идентификатор.
да хоть писькой назовите.
для шаред_птр это - монопенисуальный фактор.

eXmire
> Это может быть вообще не указатель, а просто индекс.
не может.
безотносительно к тому,
как там все устроенно внутри самого апи.

функция возвращает именно указатель.
это - синтаксис языка.

я поясню мысль:

handle foo(); // <—- вот это хэндл. 
 // по факту это может быть указателем, либо чем то ещё
 // в будущей реализации они могут запросто поменять тайпдеф.
 // для клиентов это будет прозрачно, 
 // если они не будут закладываться на то, 
 // что именно там тайпдеффицо
handle* foo(); // <—- а вот это - указатель. 
 // безотносительно к тому, что чем на самом деле является сам handle,
 // функция возвращает указатель
 // и клиенты вправе на это закладываццо

eXmire
> какой смысл приобретает операция разыменовывания в случае
> shared_ptr<GLFWwindow>?

абсолютно все тоже самое, что и обычно - референс на ресурс.

#86
2:20, 5 ноя 2016

Это всё из-за спайса табов.

Страницы: 1 2 3 4 5 6
ПрограммированиеФорумОбщее

Тема в архиве.