Страницы

Поиск по вопросам

четверг, 13 декабря 2018 г.

Оператор присваивания

Почему в операторе присваивания мы возвращаем *this, а не просто this?
Matrix & Matrix::operator =(const Matrix& m2) { if (this != &m2) { (Matrix(m2)).swap(*this); } return *this; }
Matrix Matrix::operator +(const Matrix &m2) { if (m2.columns != this->columns || m2.rows != this->rows) { std::cout << "Error" << std::endl; exit(1); }
Matrix temp(this->rows, this->columns); for (int i = 0; i < this->rows; i++) { for (int j = 0; j < this->columns; j++) { temp[i][j] = m2.matrix[i][j] + this->matrix[i][j]; } } return temp; }


Ответ

Возвращать из оператора присваивания вы можете что угодно (или вообще ничего). Главное, чтобы в операторе присваивания, как и в любой другой функции, тип значения, указанного в return, совпадал с (или был приводим к) типу возврата, указанного в объявлении функции.
Вы же сами написали, что ваш оператор присваивания имеет тип возврата Matrix &. Это значит, что в return вам придется указывать lvalue типа Matrix. *this таким lvalue является, а this - не является.
Тем не менее никто вам не запрещает написать оператор присваивания, который будет возвращать, например, Matrix *. В таком операторе присваивания вы можете возвращать this
Matrix *Matrix::operator =(const Matrix& m2) { ... return this; }
Это будет весьма странным типом возврата для оператора присваивания, но ничего нелегального тут нет.
Другими словами, что вы сами указали в типе возврата функции - то и возвращайте. Так что вопрос о том, почему в вашем случае возвращать надо именно *this - это вопрос именно к вам. Вы сами так захотели.

Параметры функции по умолчанию

В стандарте ES-2015 появилась возможность задавать параметры функции по умолчанию, выглядит это так:
function name(name = 'noname') { console.log(name); } name()
Однако такого же эффекта можно было добиться с помощью хака:
function name(name) { var name = name || 'noname' console.log(name); } name()
При этом Babel транслирует такую функцию вот так:
function name() { var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'noname'; console.log(name); } name();
Какой вариант правильнее: как предлагает Babel или с использованием логического ||?


Ответ

Правильнее как бабель, разумеется. Потому что например:
> "" || "default" -> "default"
и если вы захотите в свою функцию передать пустую строку, то поведение её будет слегка неожиданным.

Фон или картинку на картинку CSS

Подскажите самый простой и кроссбраузерный вариант наложения фона или картинки на картинку. Нужно тупо затемнить.
Гуглил - но там черт ногу сломит. Нужно что-то простое, а предлагают и текст засунуть, и иконки, и кучу всего.
В идеале я бы сделал свой фон для наложения, но не знаю как впихнуть.

alt


Ответ

Здесь для наглядности сделал градиент. Если вы не знали то в css можно перечислять свойства так свойство: значение , значение2 т.е. через запятые. первое значение самое высокое, затем второе оно выше третьего и.т.д.
.darker { width:300px; height:300px; background:linear-gradient(to right, transparent 50%, rgba(0,0,0,0.5) 0), url(http://gdefon.org/_ph/8/1/478317672.jpg) }


Как исключить из sql запроса несколько записей?

Пишу поиск:
$result=mysql_query("SELECT `id`,`status`,`live`,`game`,`category`,`title`,`time_published`, `url` FROM `news` WHERE `status`='1' AND `id`<>'70' AND `title` LIKE '%$query%' order by `time_published` desc");
Как из выдачи исключить не только запись с id=70, но и ещё несколько записей?
То есть в строку
AND `id`<>'70'
нужно передать несколько значений, но как это сделать, чтобы каждый раз не писать AND...?


Ответ

Попробуйте так:
$result=mysql_query("SELECT `id`,`status`,`live`,`game`,`category`,`title`,`time_published`, `url` FROM `news` WHERE `status`='1' AND `id` NOT IN (70, 60, 50, 30, 1) AND `title` LIKE '%$query%' order by `time_published` desc");

Перевод char или String в двоичный код (Java)

Ребят, вопрос, в принципе, не такой и сложный, однако, я гуглил, но не нашел толкового ответа. Как в Java перевести символ (char или даже лучше String) в двоичный код? То есть дана строка Str = "abс";, нужно перевести её в тот же стринг, но уже двоичным кодом: 1100001 1100010 11010001 10000001


Ответ

Для этого есть готовый метод:
String a = Integer.toBinaryString('a'); System.out.println(a);
Выведет на экран:
1100001
Соответственно, если необходимо перевести целую строку в двоичный код, а не отдельный символ, можно написать для этого свой метод, например:
public String stringToBinary(String s) {
StringBuilder answer = new StringBuilder();
for (int i = 0; i < s.length(); i++) { char c = s.charAt(i);
answer.append(Integer.toBinaryString(c)).append(' '); }
return answer.toString(); }
Более красивое решение на Java 8:
public String stringToBinary(String s) { return s .chars() .collect(StringBuilder::new, (sb, c) -> sb.append(Integer.toBinaryString(c)).append(' '), StringBuilder::append) .toString(); }

Оператор для нескольких объектов

Есть ли в c++ возможность, позволяющая применять оператор для нескольких объектов? Короче, что-то типа этого:
int i = 5; if (i == { 1, 2, 3, 5 } ) // if (i == 1 || i == 2 ...) { cout << "Hello world!" << endl; }


Ответ

В комментарий не помещаюсь...
Чтоб одним оператором и именно ==
template class Has { private: vector data; public: explicit Has(initializer_list lst):data(lst){} bool operator ==(const T& value) const { return find(data.cbegin(),data.cend(),value) == data.cend(); } };
template Has in(initializer_list lst) { return Has(lst); }
int main() { int i = 5; if (in({1,2,3,4,7,8}) == i) // Без in - if (Has({1,2,3,4,7,8}) == i) { cout << "Found
"; } }
Это путь чуть длиннее, но зато не нужно писать явно тип - ну, in
Если через функцию - то можно воспользоваться функцией с переменным числом аргументов.
Но стоит ли эта овчинка выделки?

Повторное использование кода и проблема множественного наследования в C#

Существует следующая структура приложения:

Реализация метода Id из интерфейса IGetId одинаковая везде. Но, исходя из этой структуры его нужно будет каждый раз переписывать в каждом классе, имплементирующего интерфейсы, порожденные от IGetId.
Если бы не было BaseModel это в принципе не было бы проблемой, т.к. можно было бы вынести реализацию этого метода в какой нибудь абстрактный класс AGetId и от него наследоваться, но множественное наследование не поддерживается, а композиция в данном случае нарушает целостность.
В PHP существует очень удобный инструмент - Trait. Он отлично решает данную проблему, но, к сожалению, в C# такого функционала нету.
В C# есть нечто похожее - extension methods, хоть это и совершенно разные вещи. Я пробовал сделать что-то с использованием методов расширения, но получилось на мой взгляд "не очень":
IGetId
public interface IGetId { int Id { get; } }
Extension methods
public static class CoreExtensions { public static int Id(this IGetId obj) { return obj.Id; } }
В любом случае, это не дало ожидаемого результата, мне по прежнем нужно реализовывать Id в каждом классе.
Существуют ли какие-то средства для решения данной проблемы?


Ответ

Я бы предложил такую иерархию наследования:
// библиотечные интерфейсы interface IGetId { int Id { get; } } interface IPerson : IGetId { string Name { get; } } interface IAddres : IGetId { string City { get; } }
// универсальный базовый класс class BaseModel { /* ... */ }
// вспомогательный класс abstract class BaseModelWithId : BaseModel, IGetId { int id; public int Id => id; }
// реальные классы class Person : BaseModelWithId, IPerson { public string Name { get; set; } }
Необходимость реализовывать IGetId в Person отпала.

Хотя в общем случае вы правы, trait'ов не хватает. Есть хорошие шансы, что они появятся в будущем C# 8.