Чрезмерное использование 'этого' в C++ [дубликат]

Начальный график:

library(ggplot2)
p <- ggplot(Golden_Egg_df, aes(x = month, y = egg_diameter)) +
  geom_point() + geom_line() + 
  stat_QC(method = "XmR")

Вот один вариант, в котором мы используем ggplot_build для извлечения данных из красных линий. Вы можете прочитать больше об объекте ggplot_build здесь: https://rud.is/books/creating-ggplot2-extensions/demystifying-ggplot2.html#the-ggplot_built-object

[111 ]

thres содержит значения у красных линий.

thres
#[1] 0.7319105 2.3820961

Если вы хотите выделить только точку выше (или ниже) этих значений, добавьте еще один точечный слой с подмножеством исходных данных

p + geom_point(
  data = subset(Golden_Egg_df,
                egg_diameter > max(thres) | egg_diameter < min(thres)),
  shape = 21,
  size = 4,
  col = "red"
)

enter image description here [ 119]

23
задан Mogsdad 27 September 2015 в 01:51
поделиться

14 ответов

Your version is a bit cleaner, but while you're at it, I would:

  1. Avoid leading underscore: _x is ok until somebody chooses _MyField which is a reserved name. An initial underscore followed by a capital letter is not allowed as a variable name. See: What are the rules about using an underscore in a C++ identifier?
  2. Make the attribute private or protected: the change is safe if it compiles, and you'll ensure your setter will be used.
  3. The this-> story has a use, for example in templated code to make the field name dependent on your type (can solve some lookup issues).

A small example of name resolutions which are fixed by using an explicit this-> (tested with g++ 3.4.3):

#include <iostream>
#include <ostream>

class A
{
public:
  int g_;
  A() : g_(1) {}
  const char* f() { return __FUNCTION__; }
};

const char* f() { return __FUNCTION__; }
int g_ = -1;

template < typename Base >
struct Derived : public Base
{
  void print_conflicts()
  {
    std::cout << f() << std::endl; // Calls ::f()
    std::cout << this->f() << std::endl; // Calls A::f()
    std::cout << g_ << std::endl; // Prints global g_
    std::cout << this->g_ << std::endl; // Prints A::g_
  }
};

int main(int argc, char* argv[])
{
   Derived< A >().print_conflicts();
   return EXIT_SUCCESS;
}
27
ответ дан 29 November 2019 в 01:45
поделиться

Многие люди используют это, потому что в их IDE появится список идентификаторов текущего класса.

Я знаю, что я делаю в BCB.

Я думаю, что пример, который вы приводите в конфликте имен, является исключением. Однако в Delphi правила стиля используют префикс (обычно «a») для параметров, чтобы избежать именно этого.

3
ответ дан 29 November 2019 в 01:45
поделиться
class MyClass
{
public:
  int m_x;
  void f(int p_x);
};


void MyClass::f(int p_x)
{
  m_x = p_x;
}

...is my preferred way using scope prefixes. m_ for member, p_ for parameter (some use a_ for argument instead), g_ for global and sometimes l_ for local if it helps readability.

If you have two variables that deserve the same name then this can help a lot and avoids having to make up some random variation on its meaning just to avoid redefinition. Or even worse, the dreaded 'x2, x3, x4, etc'...

0
ответ дан 29 November 2019 в 01:45
поделиться

If you have a problem with naming conventions you can try to use something like the folowing.

class tea
{
public:
    int cup;
    int spoon;
    tea(int cups, int spoons);
};

or

class tea
{
public:
    int cup;
    int spoon;
    tea(int drink, int sugar);
};

I think you got the idea. It's basically naming the variables different but "same" in the logical sense. I hope it helps.

-2
ответ дан 29 November 2019 в 01:45
поделиться

Мне не нравится использовать «это», потому что это атавистично. Если вы программируете на старом-добром C (помните C?) И хотите имитировать некоторые характеристики ООП, вы создаете структуру с несколькими членами (они аналогичны свойствам вашего объекта) и создаете набор функций, которые все принимают указатель на эту структуру в качестве своего первого аргумента (они аналогичны методам этого объекта).

(Я думаю, что этот синтаксис typedef верен, но это было давно ...)

typedef struct _myclass
{
   int _x;
} MyClass;

void f(MyClass this, int x)
{
   this->_x = x;
}

В На самом деле, я считаю, что старые компиляторы C ++ действительно скомпилируют ваш код в приведенную выше форму, а затем просто передадут его компилятору C. Другими словами - C ++ в какой-то степени был просто синтаксическим сахаром. Поэтому я не уверен, почему кто-то хочет программировать на C ++ и возвращаться к явному использованию «this» в коде - может быть, это так »

-1
ответ дан 29 November 2019 в 01:45
поделиться

It's more normal in C++ for members to be initialised on construction using initialiser.

To do that, you have to use a different name to the name of the member variable.

So even though I'd use Foo(int x) { this.x = x; } in Java, I wouldn't in C++.

The real smell might be the lack of use of initialisers and methods which do nothing other than mutating member variables, rather than the use of the this -> x itself.

Anyone know why it's universal practice in every C++ shop I've been in to use different names for constructor arguments to the member variables when using with initialisers? were there some C++ compilers which didn't support it?

0
ответ дан 29 November 2019 в 01:45
поделиться

In my opinion this tends to add clutter to the code, so I tend to use different variable names (depending on the convention, it might be an underscore, m_, whatever).

0
ответ дан 29 November 2019 в 01:45
поделиться

class MyClass{
public:  
  int x;  
  void f(int xval);
};
//
void MyClass::f(int xval){  
  x = xval;
}
0
ответ дан 29 November 2019 в 01:45
поделиться

Я всегда использую соглашение об именах m_ . Хотя мне в целом не нравится «венгерская нотация», мне очень полезно очень четко видеть, работаю ли я с данными членов класса. Кроме того, я обнаружил, что использование двух одинаковых имен переменных в одной области слишком подвержено ошибкам.

1
ответ дан 29 November 2019 в 01:45
поделиться

Лично я считаю, что вам не следует бороться с существующими соглашениями о кодировании. Как пишет Саттер / Александреску в своей книге «Соглашения о кодировании на C ++»: не переживайте по мелочам. Любой может прочитать одно или другое, независимо от того, стоит ли перед ним «this->» или «_» или что-то еще.

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

Если вы, в конце концов, обнаружите, что есть веская причина для его изменения, не делайте этого вручную. В лучшем случае ваша IDE поддерживает такие «рефакторинги». В противном случае напишите сценарий его изменения. Последним вариантом должен быть поиск и замена. В любом случае у вас должна быть резервная копия (система контроля версий) и какое-то автоматизированное средство тестирования. Иначе вы не получите от этого удовольствия.

3
ответ дан 29 November 2019 в 01:45
поделиться

Использование 'this' таким образом - это IMO не запах кода, а просто личное предпочтение. Поэтому это не так важно, как согласованность с остальным кодом в системе. Если этот код несовместим, вы можете изменить его, чтобы он соответствовал другому коду. Если, изменив его, вы внесете несогласованность с большей частью остального кода, это очень плохо, и я бы оставил его в покое.

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

2
ответ дан 29 November 2019 в 01:45
поделиться

This usage of 'this' is encouraged by Microsoft C# coding standards. It gives a good code clarity, and is intended to be a standard over the usage of m_ or _ or anything else in member variables.

Honestly, I really dislike underscore in names anyway, I used to prefix all my members by a single 'm'.

3
ответ дан 29 November 2019 в 01:45
поделиться

Согласен. Мне не нравится это соглашение об именах - я предпочитаю такое, в котором существует очевидное различие между переменными-членами и локальными переменными. Что произойдет, если вы оставите это ?

0
ответ дан 29 November 2019 в 01:45
поделиться

Field naming has nothing to do with a codesmell. As Neil said, field visibility is the only codesmell here.

There are various articles regarding naming conventions in C++:

etc.

10
ответ дан 29 November 2019 в 01:45
поделиться
Другие вопросы по тегам:

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